HACKER Q&A
📣 zackoverflow

Programmers who don't use autocomplete/LSP, how do you do it?


I am totally fascinated by programmers who don't use many of the IDE features I take for granted today: autocomplete, language servers, and recently copilot

So to the devs who don't use these tools, how do you do it? Do you just remember every type and field in a codebase? What does your flow look like?

One example is that I cannot live without the language server go-to-definition feature. What do you do if you need to look up the definition/implementation of some function which is in some other file?


  👤 daltonpinto Accepted Answer ✓
This question reminds me of the first time I met a blind programmer.

I asked him how he managed to code, and he replied with something that stayed with me: a good programmer should organize software in such a way that every piece of code has a clear and logical place. The organization should be so intuitive that anyone could build a mental model of the structure and navigate it easily, even without seeing it.

It felt like something out of a Yoda or Mr. Miyagi lesson. Skeptical, I asked his colleagues if he was truly able to code or if he was just exaggerating. To my surprise, they told me not only was he capable, but he was the best programmer they had ever worked with. They said no one else came close to writing code as organized as his.

That conversation changed my perspective. Ever since, whenever I’m unsure where to place new code, I don’t think about DDD or any specific methodology. Instead, I try to follow the logic and structure of the project in a way that feels natural and easy to follow later.

Later in life, I met two other blind programmers and heard similar stories about their ability to produce well-organized code.

To bring this back to the original question: I view LSP/IDE features the same way those programmers view "visual aids." Code should be organized according to a clear and logical structure that makes it easy to navigate.

Relying on features like Ctrl+Click to find where things are located worries me. Why? Because it can mask structural flaws in the codebase. If we can't intuitively figure out where something belongs, that’s a sign the codebase lacks structure—and that should motivate us to refactor it.

Not only do I avoid using LSP features, but I’m also opposed to their use. While they can help with navigation, they may prevent developers from experiencing and addressing the underlying structural issues in their code.


👤 jasonpeacock
You should try turning off those features yourself for at least a month and see what happens ;) You’ll learn the answers yourself, much better than us trying to explain them.

You’ll learn where all the reference docs live for your language, libraries, and frameworks, and along the way you’ll learn more by actually reading the docs.

You’ll learn the value of good project organization and file naming, and explicit import statements.

And you’ll learn that the speed of typing, even long method names, is not the limiting factor of your productivity.


👤 modernerd
I work with two types of LSP/LLM-averse programmers:

1. The HLSP user

This group does use an LSP, it turns out, only via you as the conduit: you are their Human Language Server Protocol. They'll ask, ‘can we pair today?’. From that point, navigating code, looking up method names and signatures, and flagging syntax errors before runtime or compile time is your job. How they find their way around when you're not there is unclear, but it's likely slower.

2. I am one with the machine

This crowd has been wrangling code long before IDEs, LSPs and LLMs. They've amassed a terrifying arsenal of tools to find files and references, bulk-rename, pull up docs, and twiddle bits in ways that looks fluent and natural enough when _they_ do it but would take months or years for you to learn if you didn't give up and go back to your IDE. When you ask them _how_ they just did something, they either pull up a short page of Elisp and say, "it's really quite simple we just reverse the node tree and iterate over the folded quarkenspace", or — if they're a vim user — say something like, "oh, that's just the hiboscus plugin, but piped through smark".

So the response to "how do you do it?" seems to be broadly summed up as, "the way we've always done it".

Group 2 isn't necessarily _better_ than LSP/autocomplete/heavy LLM users (people who are very proficient with more modern tools can look like magicians too). The LLM-free crowd were just forced early to become proficient, they've gotten very good with their home-rolled methods, and — in many cases — they probably wouldn't benefit that much from LSPs, or they use them but with features that bug them switched off.

Group 1 would probably better be served by an LSP but either don't believe in the benefits or is just comfortable with their current setup and feels no pressure to change.


👤 thwarted
The shell is my development environment. I open up new terminals and shells willy nilly. I find cli tools like find/fd/grep/rg are useful because I rarely need to find only the definition of a function, but rather other call sites too, to find out how it is being used. I think being surrounded by the code and being able to slice and dice it leads to a certain kind of familiarity that a tool that takes you right there doesn't afford. I like fast compilers, and type checking, so it doesn't matter if I can remember the types and fields. I'm not bothered by error messages or warnings, I fix them and I have a greater understanding of the code I'm writing. My editor is a pretty stock vim setup with format-on-save and syntax highlighting, but I can operate without those (in fact, I'm often hindered by some other defaults, like bad color choice (dark blue on my black terminal) that makes things hard to read. I dont have much vim customization because I can not rely on it always being there. I use a pretty basic setup that lets me be productive in just about any default unix/Linux environment. I find IDEs to have a lot of visual distractions. When I was first exposed to unix in the early 90s, programming using it just clicked for me and I've never really felt hindered by the defaults. I read man pages and the languages' stdlib docs (usually web pages) so I'm a little more than passingly familiar with what's in them and their capabilities and how to navigate them.

👤 RodgerTheGreat
Most of these tools are distractions. I don't want suggestions or needling warnings sliding around on my screen while I compose and examine programs; I want a quiet space to write and think. Focus is essential.

I organize notes and action items in a paper notebook in front of me or a text file in another editor pane. I read the code. I search and diff with standard POSIX utilities that are available in every environment. In the languages which support it, I try ideas and answer my own questions in a REPL.

Practice leaning on tooling all day and living without it will feel unthinkable. Practice doing without, and you'll find you need very little.


👤 barrell
I liken this to asking people who don’t use a GPS how they drive and if they have every intersection memorized. It’s not about absolute knowledge of a codebase, but intimate familiarity.

I also don’t think it’s a coincidence most people in the comments seem to be using some flavor of vim. I think using an editor designed before these tools were available will make it much easier than afterwards.

I’m not sure I’m the best case, but I just turned off copilot, haven’t bothered to configure my autocomplete yet in my latest neovim config, and only use an LSP so my macros can be highlighted differently. I write primarily in Clojure though, so inline docs and go to definition are just a part of life.

I don’t really have anything against LSPs, but neovim, telescope, and the repl have always gotten me where I want to go

With regards to my flow, I’ll normally have 1 vim session for every 1 project, each with 1-5 tabs open, each tab with up to 12 splits. There isn’t really structure to the tabs or splits, I’m just liberal with opening splits and conservative with closing them. To me it can be really helpful to have all the recent code I’ve been working on open at one time, and if it’s not, I just pop a new tab and start fresh


👤 jedberg
This post just gave me an epiphany. I work with some programmers in their 20s. They are some of the best programmers I've ever met. But they never seem to enter "flow state". In fact, they welcome distractions. And now I think I know why.

When I was coming up, you needed to enter flow state to be a good programmer. Because you had to keep track of all the functions and their signatures, all the different flows and objects, all the different files. And if you got interrupted, you had to reread the code to "load" all that back into your working memory.

But now the tools do that for them. They can click on a function and see the definition. The copilot and autocomplete will keep track of all the minutiae for them. So they don't need flow state to be productive.

This revelation may get me to actually switch from vim to something with all these modern features. Maybe it's finally time for me to try VSCode.

Especially since my kids never let me hit flow state anymore even if I wanted to!


👤 vq
I work almost exclusively in Emacs without the modern LSP-based tools. I believe I do keep more in my head than programmers that use more advanced IDEs.

In code I have control over myself I avoid imports that doesn't enumerate all imported symbols. That is I always use the import Library (symbol) syntax in Haskell and never do wildcard import in Python.

When coding C I sometimes use tags so that I can go to definitions quickly, I should probably use it more than I do to be honest.

I do use hippie-expand for quick auto-completion but it is completely textual, it has no understanding of the programming language it currently works on which makes it much less powerful of course but it also has some benefits.

I always have the documentation very reachable, I use a search keyword in my browser to search on hoogle. I type H symbol/type-expression and I quickly find the documentation.

I do use Visual Studio on a Windows box for working on a C# codebase a couple of times per year and when I do I always turn off that code lens thing and I find that I rely on the code navigation features quite a bit. Part of it is probably due to it being a code base that is larger and that C#(/Java)-flavoured OOP makes the code more spread out. In terser languages like Haskell (which is much terser) it is natural for more functionality or types to live in the same file which means that you get much further with just simple textual search.


👤 userbinator
The sibling comment about a blind programmer is very worth reading, because it is relevant to what I've observed about other (non-blind) programmers who are highly skilled: they do not need tools to tell them what to do, because they have completely internalised the structure of the program and can think about it as a whole. Incidentally, one of the things I often do when solving a problem --- be it finding a bug or fixing it, or implementing a new solution --- is to close my eyes and think deeply about it, without distraction.

I don't use IDEs either. A plaintext editor and a console window (for compiling, testing, and the occasional grepping) is enough. IMHO someone who is reliant on IDEs and autocomplete is in the same category as not knowing how to type without looking at the keys on the keyboard --- yes, you can get by, but you will never be able to code as fluently and effortlessly as those who can think deeply about the code entirely in their brain, and you'll be frequently writing code that looks reasonable when viewed in isolation but obviously redundant and/or inefficient if considered as part of the bigger whole.


👤 perrygeo
As someone who started programming on Solaris UNIX, then Linux workstations, in the late 90s, there just wasn't an option. You used vi or emacs or you didn't work.

I'm not saying it was the good old days but it was not a significant barrier to doing what we wanted to do. Code is code and ultimately you need to have a clear mental picture of the codebase, regardless of your tools. LSP isn't valuable because it allows novel functionality (there are dozens of different techniques for discovery within a codebase). LSP is valuable because you have an efficient way to "query" your codebase for contextual information directly in the editor window.

But you can build that knowledge through other means, you just need another terminal window and external tools.

The understanding of the codebase is what maters. LSP is a means to that end, making an already common task slightly more efficient.

> look up the definition/implementation of some function

Text is effective. git grep "def foo"

Autocomplete engines work on text too, based on the contexts of the buffer or files in the directory.

Static analyzers have always worked wonders in identifying LSP-like warnings.

Compilers and debuggers give you access to state and type information.

This stuff has been around for decades. LSP just makes it more convenient and packages it into one UI.

For what it's worth, I'm 100% in on LSPs for my work these days. But if LSPs disappeared tomorrow, I could revert to the old ways with only a small hit to productivity.


👤 bigpingo
I hate annoying distractions, be it popups, beeps, notifications, alerts, auto brace/quotes/etc and autocomplete prompts. I turn all of that off in every program because I want to be in total control of the computer.

When it comes to autocomplete specifically I initially turned it off because I was mainly a C++ programmer and C++ autocomplete has just never been good enough and a half-working autocomplete is just worse than nothing at all because you end up stalling and waiting for the prompt. But eventually I just grew to hate it for all languages because it interrupts flow and "pipelining".


👤 hliyan
When you have a good mental model of the code base you're working on (and the libraries you use), you don't really need a lot of IDE features, and IDE features can sometimes hamper the formation of such a model. Let me explain:

Twenty years ago, my IDE was two terminal windows running VI, vertically tiled. On the left, I open header files, and on the right, source files (I was a C++ programmer). When I wanted to look up method signatures or member names, I would quickly look it up from the relevant header file. This could take anywhere between 5-60 seconds.

If you remind me that IDE features could improve this by a factor of 10x, you're absolutely right. But if we apply Amdhal's law to developers, their biggest time waste is often not the physical act of coding, but fixing logical and structural issues in their programs. And the best way to prevent such high level issues is for the programmer to have a good mental model of the code base.

So, the possession of a good mental model of your code base obviates the necessity (but not the convenience) of IDE features such as autocomplete/intellisense. But at the same time, reliance on such features hampers the formation of a good mental model.

My current compromise is to rely more on the "Go to definition" function than auto-complete.


👤 SoftTalker
I turn off autocomplete everywhere I can. Whether web searches, composing code, or anything else, I do not want the computer anticipating what I am about to type. I find it is often wrong, and always distracting.

Yes, I try to learn the language well enough that I know the parameters of common functions. If I don't, I consult the docs. If I need to find the definition of a function in another file, I use grep.


👤 scop
I have jumped around over my career: Sublime -> Vim -> Emacs -> VSCode -> Neovim -> Cursor, which is now my daily driver.

However, I still relish in the ability to open up a nerfed Sublime or basic Vim install where it’s just me and the text. I do so when I want particular lucidity in my thought process and code composition.

Then I can always fire up heavier tools for code review after the fact. How do I “do” it? I got really good at grep’n my way through a code base. It’s amazing what grep/ack/rg/etc can tell you when you know what to ask. And if you don’t know what to ask, well finding that answer is going to teach you a lot more than just hitting Tab on autocomplete or GoToDef.


👤 wruza
Some of us learned (and later shared it) at the times when you had to close an editor to access digital manuals. We went through different phases of “dev envs”, some of which were not that advanced (or later died), and we invented our own stable ways to overcome the issues. Some people chose complete off-road, some found a balanced approach. It all turned into various knowledge bases, muscle memory, tools, habits - that we shared. Inadvertently that created more people who do the same but might never have the issue in the first place.

When someone tries to repeat that from an IDE/LSP perspective, it obviously feels slow, akin to speaking a new language for the first time. Does one need this language? It’s hard to tell.

Problems show different contrast to people with different backgrounds. My personal position here is that if you shouldn’t solve non-problems. The set of problems you decide for yourself based on your experience.

I’m a balanced guy, btw. Sometimes I just sit and try to force upgrade my dev env. What sticks sticks. What doesn’t, goes to hell. I’m using ALE (nice multi-LSP tool) and all the tools I know since ancient times. Copilot writes what I call boilerplate, and I neither trust it nor have the need to write it. Passing my real-business functions to LLMs usually produces unfixable mess, so if someone knows another way for it to be useful, I’m all ears.


👤 gregjor
I use vim with ctags. vim has good autocomplete but I don't use it much -- I rely on memory and looking things up in the docs. With ctags I can jump to definition/implementation of a function.

ctags has worked since the early 1990s.

Check out this video: How to do 90% of what plugins do with just vim.

https://youtu.be/XA2WjJbmmoM


👤 throwaway81523
I use Emacs and sometimes I open a window to bring up a man page or code definition for some function, but I've never felt the need for a fancy IDE. You just get used to what is going on in the code. Like if you are a fiction writer and you're asked to write a new Star Trek episode, after watching a few existing episodes you would get familiar enough with the characters and milieu to not need to refer to the series bible too much. An IDE that pops up suggestions like "Live long and prosper" or "we have 93.2357% chance of blowing up the ship, Captain" when you type the name "Spock" sounds counterproductive. Maybe I'm missing something though.

Added: it helps a lot to have real documentation, something that has gone out of fashion in recent years. Maybe these IDE's are being used as a substitute. I hadn't thought of it that way before. Hmm.

Added 2: Also, Emacs has always had TAGS (this quick navigates the editor to a function's definition given its name) and I do use that sometimes.


👤 trevor-e
This thread is certainly eye opening. It reminds me of a post I saw somewhere, maybe on Reddit, where someone was describing their experience working as an intern at an old-school tech shop. All of the developers there were hardcore Vim/Emacs users with 20+ years of experience.

The intern was tasked with a large-scale refactoring of some modules which the senior devs estimated would take months of work to complete. After shadowing a senior dev to get an idea of the work involved, they realized the dev was literally string replacing a lot of the code, hence why the estimate was ridiculously long. The intern instead loaded the project into IntelliJ and used the built-in refactoring tools to get the task done in a couple days. This caused a bit of an internal shit-storm with the product owners because the intern made the devs "look bad".


👤 jez
> What do you do if you need to look up the definition/implementation of some function which is in some other file?

Code search (ripgrep, GitHub search, Sourcegraph, git grep, or even just plain grep). You can use VS Code search but I prefer CLI tools so I can filter the output of my search with more searches—VS Code makes it hard to post-process/filter project-wide search results.

Filename search (fzf, fd, or just find).

There are cases where LSP-powered Go to Def is faster, but there are also cases where it’s less accurate. I’m talking:

- Untyped code in a graduate typed language

- References of a method name in a YAML file pulled out with reflection

- References of that method in a comment of some other method, where that method is actually the method I’m looking for.

- A one-to-one mapping of method names with some enum somewhere else, but lowercase in one spot, and all caps in the other spot.

So yes, sometimes go to def will be faster, but you’ll lose out on so many other possible references.

Another case: repos where the codebase is so large that the editor tooling is slow. Repos where I’m brand new to it, because I just need to check why some code in a third-party library is going haywire.

Grep (code search) is just so powerful.

I have a post about how to do large-scale code migrations/codemods. Everyone assumes the post is going to be about how to use high-powered, language-aware AST-based static analysis tooling. But half the post is talking about the unreasonable effectiveness of regular expressions.


👤 patchymcnoodles
For me it is actually a disturbance, especially autocomplete. So yes, I need to remember stuff, but if I cannot or just don't know the codebase, I look it up very quickly and then can learn more from looking at the specific code.

At the start of learning rust I used a bit more help from the IDE, but now not anymore.

For me it is just easier to have a much deeper knowledge instead of "only" have knowledge about the tools. A good example was when I used SVN back in the days, I only used a GUI and always struggled if something does not work out. I had basically no idea, what is really going on. So when Git became the new normal I forced myself to use the command line only and because of that I can always help myself (with Git atleast :D).

Certainly not something for everyone, but it works for me :).


👤 freehorse
I do not really belong to that group, but when I am learning a new language I avoid using LSPs and anything more than a generic autocomplete because I find that too distracting while I try to learn the language. Moreover I realised that it actually slows down my learning; I may type stuff faster but I learn and gain understanding slower compared to eg typing everything and searching the docs. In stuff I am already proficient with, it makes more sense to me as such tools help me code faster, including finding and fixing bugs faster.

As for copilot, I find it impractically distracting and I do not understand how people are supposed to code with it tbh. While coding I spend most time thinking about the code than just typing, and having random autocomplete suggestions popping up with lag while typing disturbs my chain of thoughts. Maybe if I was writing more boilerplate I would have liked it more, or I am using it wrong somehow, or maybe one gets used to it after some time. I sometimes use copilot chat though.


👤 d3VwsX
My personal observation, even if this is similar to what others already said: I found that in some (two? three?) big Java-based projects I worked on, where almost everyone used a IDE, the codebase became almost impossible to navigate or modify without using one, so I did. It was so easy to just add a method or class wherever, and it did not matter because you could just ctrl-click a name to find its implementation. It did not matter if you put 100+ methods in the same class or if you named things willy-nilly or overloaded method names.

If I was back working on a project like that, I would use whatever IDE everyone else was using. It makes no sense to fight it. But I prefer projects to not be designed for/by IDE, since that tends to make everything more readable and easy to navigate. I prefer to be able to navigate around the source-code on the command-line or use whatever generic tools to browse, and not be forced to ctrl-click my way around, and if (almost) everyone else working on the code wants that as well it is less likely that someone ruins it.

That said, I have at times also set up Emacs to use LSP or other built-in code-navigation tools, or templates (yasnippets) for generating boilerplate, for some projects. I rarely end up using it much. Usually I just jump around using built-in tools like M-x vc-git-grep or M-x rgrep. The code has to be pretty heavily designed-for-IDE to make those simple tools slow to use.


👤 javcasas
Ah, yes, autocomplete: the propagator of typos. Write it wrong once, have it copied wrong everywhere.

Go-to-definition: the band-aid for overengineering. Write 37 levels of indirection, don't pay the price.

AI programming: now you don't even have to pretend you understand the code! Bonus point: sometimes it generates from StackOverflow, but from the question, not the answer.

These are good tools, but it's easy to figure out who uses them to help themselves, and who couldn't write code at all if it wasn't for these tools.


👤 HarHarVeryFunny
I'm an old school programmer - built my first 8-bit home computer in 1978, and been programming ever since (currently Linux/C++ telecom - heavy multi-threading).

There are tools like ctags that have been around forever and build an index of definitions to let you jump to them, but personally I've never found a use for it, anymore than I ever found a utility for IDEs. I just have multiple terminal windows (or tabs) open along with my editor (emacs).

When I'm deep into a project - even a very large one, I basically just remember where everything is (as well as the code itself), or when needed just use terminal find/grep. For stuff I've written from scratch myself (vs at work working on a large legacy codebase), code organization is certainly part of it - organizing code into file-based modules. I use record/playback editor macros a lot to avoid typing, and occasionally use sed (scriptable Linux command line editor) to perform entire codebase renames etc.

I've tried modern IDEs like VS Code, but really don't find them to be a productivity benefit. I get the appeal of a single tool/environment that does it all (like old-school hard-core emacs folks who treat it as an IDE), but in terms of productivity you can work just as fast with a collection of tools rather than a single one.


👤 herbst
I feel heavily annoyed from most IDE features. I love to code in a chill relaxed way where I just write the code that I want.

I actually remember all the relevant fields and I am currently working on, or just reread the relevant code when necessary.

I wonder if syntax and cute grammar has any relevance in a world where people basically let the IDE to the coding.

I honestly wouldn't call me a good coder if I wasn't confident I could produce the same code quality on a computer with just nano or vim and no internet.


👤 ryan-c
I use vim, and program mostly in Python, Rust, TypeScript, JavaScript, C, and Bash. There are about a dozen other languages I use on occasion.

My vim configuration is moderately customized, and I regularly write code on systems I SSH into since my personal laptop is a Pixelbook.

The main things I rely on are syntax checking plugins.

I use ripgrep to find stuff in codebases, and when I'm working seriously I use an ultrawide monitor with plenty of screen space to have documentation I can glance at open.

I have a significant collection of small libraries I've written for common tasks, and often refer back to my own code across projects to figure out how to do things. Metaprogramming is something I do often too.

As another person said, thinking is my main constraint when working, not actually writing the code.

It should also be noted that I'm not primarily a "Software Engineer". I'm a Principal Security Engineer at a big tech company. If I'm working on actual code, it's generally "interesting", either a hard problem at work, or a personal side project. There tends not to be much boilerplate.

For TypeScript/JavaScript in particular, something like copilot would get in my way, as my style for this languages is extremely non-standard.

I'm not sure how much any of my coding habits have to do with it, but I regularly tear into unfamiliar codebases to fix bugs and add features, and I'm pretty good at orienting myself quickly, even in languages I haven't used before.

The first thing I did with Rust was add features to a data compression library without any prior exposure to the language...


👤 kunos
Here's my experience so far. 1) The best analogy for LSP is GPS navigator in your car. It's invaluable when you have to navigate to unknown places to do stuff but, it also slows down your ability to learn the roads of your closer neighbourhoods. I am often surprised how confused I am if my GPS sends me down a road that is closed for whatever reason and I have no idea how to figure out an alternative route even if I am driving around my place, it shows me how much I rely on the navigator to get me anywhere now.

So what using an LSP is doing for you heavily depends on the kind of code you write. Are you the kind of dev who works in pretty much a very familiar codebase for a very very long time? Then LSP could even be impeding acquiring a better mental image of your code. Conversely, if you are a coder who often ventures into different and unknown parts then LSP might make you way more productive.

2) Depending on the language, LSP can become an actual part of the language itself. When I code in languages with good LSP (C#, Rust but also C++) I often code with the LSP as my "target".. I think what I'd like to see popping up when I type a "." . In this part of the code I want to see this var and this method.. in that part of the code I want to see also this other vars and methods it gives a very good idea of what the "surface area" of a piece of code looks like.

LSP are also very good instant feedback if something you are typing is wrong. I press "." and nothing shows up? I have some error somewhere and/or the thing I am dotting is not what I think it is.

But, in order for this to work the LSP has to be REALLY good to the point that has to be close to zero doubt that if the LSP is not behaving it means it's your fault. Sadly, not many LSP ever reach this level of reliability.

This is one of the thing that made languages such as C# and Java so popular: the ability to "dot" your way through unfamiliar libraries with great ease without having to dive into documentation to discover there's a function X in some file Y that already does exactly what you are trying to do.


👤 entropyneur
I've recently experienced a sharp decline in my ability to remember anything code-related. At one point I looked at the code I wrote the day before and it felt as if I don't even know the language it's written in. I was attributing it to the age, but this thread made me realize it coincided precicely with the switch to using IDEs after 15 years of getting by with a text editor.

👤 habosa
I think lumping in LSPs to Copilot is wrong.

The LSP is a (mostly) deterministic system that surfaces information provided by the language or by other programmers (types, comments, etc) which are meant to save you time and reduce the cost of context switching.

The other is a completely non deterministic system which generates code from thin air.

That would be like comparing GPS to a self driving car. Both are certainly helpful aids but using one is not like using the other.


👤 irrational
I learned and worked for decades before these tools were available. If they still weren’t available today, you would find that you too could program without them.

👤 battle-racket
Maybe it's my ADHD, but I cannot for the life of me stand using an IDE. There's too many distractions - popups, suggestions, underlines, warnings, and a million different buttons cluttering up your screen. That along with an AI assistant would make my head explode.

All these things that supposedly "help" us code end up limiting us in severe ways because we aren't forced to think anymore. Typing, syntax checking, and recalling function definitions isn't the bottleneck to programming. If they are, maybe you're not programming.


👤 ARandomerDude
1. Memorization (i.e., knowledge) beats tooling every time.

2. Pain is the most effective way to learn.

I was a 90s kid, still just young enough to have my parents tell me to go get out a paper dictionary when I asked "what does this word mean?" It's amazing how much better it "sticks" when you have to stop, get up, open a book, and find the entry.

With a minimal vim setup, I find that I just know Linux, the language intricacies, and the codebase better than my coworkers – not because I'm smarter but because I have to manually look up things I don't know. It's slower in the moment but over time it is much, much faster.

For the same reason, I never copy/paste code that I could not have written from memory.


👤 ryukoposting
I tried copilot for a few months, found it annoying, and uninstalled it. These tools make IDEs/LSP unnecessary for my workflow:

1) regex be it grep, or equivalents built into the editor. 2) Multi-cursor editing. 3) dumb autocomplete. 4) knowing how to type fast.

About 70% of the code I write at work is C. Another 20% is Rust (which does have a nice LSP implementation that I use, though I wouldn't call it essential), and the remaining 10% is the usual bash/Python/Ruby/cmake/make mumbo jumbo.


👤 iamsaitam
I think purism is a slippery slope for experienced people, I too suffer from this to a certaint extent. It's natural to fight change as you get older and it's part of the struggle to change your behavior and adapt to the changing times.

Short comment regarding syntax highlighting, unless you have some impairement, I think everyone benefits from this. It's something that helps you recognize patterns much faster and you can skim through the code way faster than without.


👤 efxhoy
My preferred way of working is plain sublime text and the terminal. I use command line tools for linting, formatting and type checking, wrapped in “make lint”.

I find that sublime is just smart enough to go to the definition using only its “dumb” grepping based approach.

I think the hurdles of getting a nice LSP setup that works across projects in different languages and in a polyglot monorepo is a real determinant. I just really dislike spending any time configuring my editor past the basics, because I’m lazy, updates break them, I move between machines, etc. Getting comfortable with just the basic features means I have less pain maintaining my editor. It’s not a great excuse but for me it’s the path of least resistance.

I frequently pair with colleagues, some are vscode users that are heavy on LSPs and copilot. I have one greybeard colleague who runs a very sophisticated neovim setup, and spends a lot of time maintaining it. We’re all roughly equally productive at the “writing code” part of the job. What sets us apart is our skill in actual software development, which I find is completely uncorrelated to the editor setup. We all work in the tools that are most comfortable to ourselves.


👤 codazoda
> What do you do if you need to look up the definition/implementation

I have these features on (more or less) and I still use grep, ag (the silver searcher), and GitHub search. I often need to look for things my editor can’t possibly figure out. I’ve never found editors to be great at this. Then again, I probably haven’t optimized for it. I’ll admit that might be a mistake. Old habits die hard sometimes.

BTW, I’m usually looking for other people’s work or code I wrote long ago. Functions written somewhere in a vast code base that I don’t have completely checked out (because I’ve never coded on parts of it). I don’t think much about the obvious stuff, like a function in the standard library.


👤 magnetowasright
Autocomplete in code is the single most annoying thing I've ever experienced. While I do have a fantastic memory, I don't feel like it makes a huge difference? I don't quite understand the workflow using autocomplete, I suppose. If I'm typing something I know what I'm trying to achieve (with or without a more concrete implementation plan), the general context of the code I'm working with, and it is quicker and far more enjoyable for me to just type instead of dealing with a minefield of never ending pop ups from autocomplete. I know the types/fields/classes/language features/whatever because I have to in order to do whatever I'm doing. I reference the relevant code, open in other tabs in my editor. I also reference documentation. I don't really find myself wanting for more. I don't understand how using auto completion would impact needing to know that stuff anyway? I get that it's annoying and maybe less efficient to have to type out all the params and types and other predictable stuff by hand but you have to know it to make sure the option you've chosen from the potential many options suggested is correct anyway, right? It feels like less mental and physical effort to me to just type exactly what I mean instead of having to review options and double check I've chosen the right one, but I can kinda understand why that's a minority opinion. I still fuck it up or end up changing my implementation and having to revise it anyway but I definitely prefer to type.

Before I figured out how to configure Sublime Text (I used Atom until it was killed) to have JUST go-to-definition and no other LSP features enabled, I'd just do a quick couple of searches across a code base or file. It was fine tbh. Yes, a single key press is much nicer but it really wasn't that annoying to not have it. I got just go-to-definition working and was able to turn literally everything else off and I'm really happy with it.

For context, I've worked in all kinds of code bases with all kinds of quality and organisation (including lack thereof) in a variety of languages and frameworks, and I've not really felt the NEED to change. I do try VSCode and/or using more of these typical IDE features maybe once a year in an attempt to leverage these features that seemingly every other programmer feels they gain a lot from but I just HATE it. I can't stand it. I really have tried! I do assume I'm leaving some quality of life and productivity gains on the table but I've never been able to make it work for me.


👤 akerl_
I do 100% of my software development in vim. I have syntax highlighting and some auto indentation but otherwise no autocomplete, no LLMs, no vim plugins for hopping between files.

I just… write code? If I need to remember what’s in another file, I open up that file in an adjacent iTerm pane, or pull up the docs for the library, etc etc. if I want to have the program run every time I save, I run a watchexec in an adjacent pane.


👤 xlii
As many others I do use fd/rg/ctags, custom scripts, some even Perl ones; Today I’m on Kakoune but had plenty of Emacs integrations when it was my daily driver (Kakoune taught me to pipe selection through a script that echoes code fragment which works in most editors, e.g.: `|gosnip_if_err_panic.pl` with `responseErr` selected).

I think that the reasons I’m not using IDEs/LSP are more worthy sharing:

First one is that I cannot use one. While the main language I’m using has relatively ok LSP, the codebase prevents usage - as it’s ridden with circular dependencies, macros, module aliasing and multi dispatch cast chains. Everything outside of syntax highlight it unusable.

Second: I noticed that assisted coding is like GPS assisted driving. I stopped internally understanding architecture of the code when using IDEs, this disconnected my mind from the code and at some point it started to feel like shoveling. Mindlessly spit out the code at let IDE handle the rest. That made me efficient at local change but unable to build up and see „big picture”. It bothered me to the point I decided to not use them anymore.

The third thing is that I don’t take „no” (coming from software) for an answer. I often get those specific needs for code search/refactorings that IDEs/LSPs refuse to work with. E.g. I need to search customized OpenAPI specifications and link it to a macros/generated code for browsing. IDEs/LSPs cannot help as it’s not idiomatic, so I customize. And customization is a loop. You customize, you learn how to customize better, you customize more etc.

When it comes to LLM-based aids I’m at point of minimum trust. I’ve experienced so many problems with that code that I rather just disable it entirely. Example? I was setting up Ticker based waiters for Go and then in one place I accepted `time.NewTimer` local-LLM snippet instead of `time.NewTicker` in infinite loop. It was 4 lines of code and looked VERY similar as in 3 functions above (that was before code reduction phase). For those unfamiliar: Go’s ticker ticks every N time. Timer fires once. One-shot-fire in infinite loop == lock. Took 4 hours to debug.

I’m not against using LSP/IDEs. They have their use (but for Pete’s sake ask your organization leaders before feeding proprietary code into ChatGPT). They don’t work for me, I feel dumber. Maybe I’d be more efficient but I don’t care. I do this job also for fun, and GPS kills the fun part for me.


👤 lispm
I load the Lisp code of a project into the Lisp environment, which is the program and the development environment in one thing. Then all the information about the project is available in the running IDE/program combination. The thing then is fully reflective and introspective.

An example is GNU Emacs itself. For Emacs Lisp it is both the IDE and the application environment.

Similar integrated systems existed already earlier for Lisp and Smalltalk. Interlisp, the MIT Lisp Machine, Smalltalk 80 and others were examples where the IDE and the code was integrated.

OTOH, the combination of GNU Emacs and external Lisps, like Common Lisp systems, was basically LSP before LSP existed. There were tools like ILISP, which connected GNU Emacs to various external Lisp runtimes (which have all the development information about the loaded code). SLIME replaced it at some point in time and usually connected to external Lisps via network connections.


👤 Rendello
I like syntax highlighting and basic automatic indenting, but not much beyond that. I can't stand autocomplete if there's an automatic popup. I tried some LSP stuff and it was quite nice but I couldn't turn off some features in my editor and they distracted me. The thing I really can't stand is automatic closing of parentheses!

👤 zelphirkalt
If they are good at what they do, I think they are simply good at keeping things in mind, what everything is called, developing a good mental model.

Personally I often write code without LSP, and use pure text completions with Emacs (words of opened buffers) and cycle through them. I know the language well enough, or I look things up in their documentation until I know them well enough. Occassionally I will also use LSP, if it exists and is easily configured and works well.

Go to definition: If I don't have it, I develop a map of the project in my mind where I find what in a project. I have also observed how projects become not so well organized, when people rely too much on always being able to "navigate through code". One does not need to pay much attention to module naming or class names and the like, if one never na igates the file tree to go to the file. Sometimes I have to rgrep/ripgrep.


👤 exDM69
In Vim, the "stupid" auto complete will get 80% of the way there and works without setting up a language server and it works for any language.

By default it will give all the identifiers in all open files. Having a few of the relevant files open in the editor will get you pretty far.

I do use LSP in other environments where it is available but I still do a lot of my work with just plain vim because I jump between code bases a lot and setting up LSP for C/C++ needs some extra steps to work.


👤 codr7
I feel that's a big issue with learning a language in an IDE.

I've written a ton of C# and I don't remember shit about methods in the standard library, because it's all there, and getting worse with AI. Not to mention the detrimental effect that the constant interruptions must have.

I use IntelliJ for Java, but since I learned the language and standard library long before fancy IDEs were a thing I barely notice the blinkenlights.


👤 mgaunard
Good code should be designed such that it's easy to find where things are to begin with.

If you need an IDE, that just means your code is a mess.

Ironically, the more messy the code is, and so the more you need the IDE, the more likely it is that the IDE will have trouble coping with the code, becoming extremely slow, or randomly failing to jump into some functions.

Ensuring your codebase remains workable without an IDE is actually a good litmus test for quality.


👤 wenc
I used to code in pure vim, so no autocomplete and syntax checking. It is definitely possible.

Is it a better way to work though? Well, in some ways, it forces you to use more cycles in your head, so you do gain proficiency, and you can spot mistakes more quickly. This is a skill.

But once I started working on larger codebases and higher complexity code, I felt it was better to redeploy those brain cycles toward thinking more about architecture, and letting the LSP check the code. With an LSP, I'm now able to write more correct code in fewer iterations.

Like everything it's a trade off. Am I impressed by people who can do complex mental arithmetic? Yes, but for anything complicated that I'd rather not get wrong, I will reach for a calculator. Same idea here.


👤 Jugurtha
I don't use any of these out of ignorance first, laziness second, and incompetence third.

I didn't know about them, and I had spent a lot of time with the documentation and code of everything I touched (language, dependencies, etc). Looking things up reinforces this. The value of a feature such as autocomplete is marginal to me as a function of the effort I have to make to learn how to use it properly, the frustration of using it improperly, and the added steps to fix a blunder, so I just don't bother with it.

I also have a habit of having the documentation/book/code of a dependency open nearby and doing my look-ups there.

A lot of time is spent refining existing code, debugging, optimizing, refactoring, etc...


👤 spamizbad
So back in the day before LSPs:

Typically I'd leverage 2 large monitors and keep at least 3 editor "views" into code open at once: one for what I was actively working on and 2 others that would contain reference code. You also take considerable care as to how you organize the code, so that grepping for definitions is easy. If I needed to see how a particular object or function worked, I'd pull it up in one of the auxiliary code windows - which would typically start with a grep alias command that would have a shortcut to open it in a designated emacs buffer window. Not anywhere near as convenient as an LSP but it got the job done.


👤 jcalvinowens
I do most of my programming work in vim on a machine with no X. I will literally use grep to look for definitions, and it really amuses me now much this horrifies people. At the risk of sounding like an ass... I'm exceptionally productive, it works for me.

I feel very strongly that the key to getting things done in the real world is the ability to identify simple tractable solutions to complex problems, not some ability to crank out mountains of code by brute force.

If I'm constantly needing to search for definitions, that tells me I've failed to spend enough time studying the codebase before trying to patch it. I'll shelve what I'm trying to do, and go study the code for awhile before trying again. How can I possibly hope to see the optimal solution, when I clearly don't even understand the basics of how the code is organized!?

I use tools like cscope when jumping into something completely new to me, but I find they quickly stop being useful once I've gotten to know the project.

Spending hours to days studying a large complex codebase is a necessary prerequisite to successfully working with it, IMHO. Shiny IDE tools can juice short term productivity by allowing you to brute force through code you haven't taken the time to understand, but that costs you a lot in the long term.

Of course, you can use the IDE tools for code study: I'm not saying they're inherently bad.


👤 CarVac
I want to be able to reason about my code without sitting in front of it, so I simply don't use those tools and this understanding of the codebase builds over time.

When you're working in one area of it, you read it and make additions in it repeatedly, and eventually your familiarity increases until you have mastery.

Then you can code anywhere, anytime, and merely type it in when you get back to the keyboard.

It's like learning a (human) language. As an analogy: "[foreign language] speakers who don't use a dictionary, how do you do it?" But the foreign language is your codebase. Learn it.


👤 finnthehuman
> So to the devs who don't use these tools, how do you do it?

This is the kind of question where you can easily go get a much better and more comprehensive answer on your own by experiencing it yourself.


👤 iio7
Before mobile phones where a thing, we used to memorize the phone numbers of every family member and friend and co-worker, etc. The numbers we rarely used, we wrote down or looked up in the phone book. When you got a new number, you maybe wrote it down, then after having dialed it a couple of times, it stuck. This didn't really require any effort, it was just the natural way of doing things.

Then came the mobile phone with the ability to store contacts, today I can't even remember my wife's number.

I have coded for more than 40 years and I hate autocomplete, language servers, etc. I don't use any of it because I have found (after having tried to use it all) that, just like with phone numbers, you don't remember much if you use all of that and you have to make a real effort, but things just don't stick the same way. But if don't use any of that, you only have to look things up in the beginning, then occasionally, then rarely or never again and more things just stick, you get faster in a natural way and you understand your code better. You also think deeper about how to structure your code and how to organize everything.

If you always use a crutch to help you walk, you will never walk by yourself. The crutch will look like it is helping you, but that's only in the beginning, eventually it will hinder you and hold you back.

That's my 2 cents.


👤 ximm
I prefer using language agnostic tools where possible because that is both simpler and allows me to use the same tools with every language. For example, git, grep, or vim all work on any text file. vim has a few language specific settings though (e.g. syntax highlighting).

👤 jgb1984
Been using Debian and vim for almost 25 years now. Tried many IDE's but they're distracting, bloated and slow.

My main language is python and for that I use jedi-vim (which allows me to jump to a definition), fzf with ripgrep to easily open files and search for specific things, and ALE that runs ruff formatting and linting. Tmux to keep my terminals organized and openbox to make it stylish and stay out of the way.

No LSP, no autocomplete, and sure as hell no AI nonsense.


👤 diegof79
In my experience, code navigation features are necessary for writing code comfortably. If you mean only auto-complete by LSP, then yes, it saves you some typing or function lookup, but that’s not the main benefit for me.

Years ago, I worked for a long time using Smalltalk (VisualAge Smalltalk, to be more specific). Older Smalltalk versions didn’t have autocomplete. But it wasn’t a problem because Smalltalk has excellent code navigation features: find implementations of a message, find callers, and evaluate code inline. With those features and some code conventions, I never felt the need for autocomplete.

Perhaps it’s my Smalltalk legacy, but nowadays, I use the most Cmd/Ctrl-Click to navigate to the implementation, read the sources, and use the “find references” feature. I don’t know if the LSP implements those features, but reading the sources gives me much more information.

Before programming in Smalltalk, I did some C++ and Java programming. While all Java IDEs had autocomplete, C++ autocomplete was unreliable on most tools I used. The solution is to read the docs and the source using search tools across the code base and third-party sources.


👤 alentred
In the past I have been training in a coding "bootcamp" for a while. I insisted that people new to coding use a plain text editor, like Notepad on Windows, no syntax highlighting, no autocomplete, nothing, and a command line to lint and compile the code. I only introduced the IDEs much much later, closer to the end of the bootcamp. First, I confirm that it is perfectly possible to complete rather complex projects this way. Secondly, I have no ground truth to compare my results with, but I know that most of the students appreciated the fact that they do not depend on the IDE/LSP/Copilot that much and developed their own understanding of how the things work.

I don't advocate to do the same outside of the learning process, of course. The tools help a lot (in fact, LSPs are awesome), but there are two principles that are important here I think:

- having an understanding of the underlying code, language, etc.

- being intentional about the use of the tools (e.g., invoking auto-complete with a keystroke vs an endless suggestions list; running a linter explicitly vs a code bloated with "insights" and "warning highlights", etc.)


👤 akoboldfrying
"Back in my day, goin' to foo's definition meant packin' yer bags for a four-day horse trek over the mountains..."

Seriously though, pressing Ctrl-B in JetBrains IDEs is half my workday.

I just tried out Copilot starting a couple of weeks ago for Advent of Code, and I'm very impressed. Easy 2x speed boost, with occasional bursts of much more. I'm mostly using Java, though I've tried Perl and it knows that too.


👤 chikere232
I use auto-indent and syntax highlighting which is sort of an IDE feature, and some other quality of life things like triming trailing whitespace on lines I edit. I also trigger compilation from the editor so I can step through the compilation errors one by one.

I know my editor (emacs) could do some of the more advanced things you mention, but it needs a bit of setup and I'm lazy. It's not really a blocker.

I look at the docs if I'm doing something new to me or have forgotten a function call. I google more complex things which often gets me more useful info than an IDE could give me, unless it's drowned by AI-slop.

If I want to dig around in a codebase I can grep for things, or just open a likely looking file and isearch for the thing.

I do git etc from the commandline, which I could probably do from emacs too but I never really bothered to.

I have nothing against IDEs and have used some at places where it was harder not to because they'd standardised on a common one. I kinda enjoy the simplicity of just having a familiar editor for any language I encounter though.


👤 pino999
I did for a very long time. I only used vanilla vim, a terminal, a couple of core utils, and documentation.

You just learn to memorize a lot, organize and design your code. It feels very similar to learning to navigate a city without map. The map will be in your head. A very similar feeling I had with code bases. I navigated a map, sometimes I knew the route towards a piece of information, sometimes I knew exactly where it was. Sometimes you add a building or a new road, but you all keep it in your head.

Nowadays I use LSP, autocomplete LLM's and what not. Makes things easier and above all faster.

I still can do without, I am just a bit slower. For small changes and simple scripts I fallback to vim. For git I still use the terminal. And I still use a lot of commandline utilities, because each IDE has a zillion of commands that do the same anyway.

For your example, nowadays I would use grep or some modern equivalent to search for definitions. And to be honest, that isn't that much slower. I can have my editor open in tmux tab and in the other my editor. You don't have to jump through files then.


👤 thedanbob
I'm a Rails programmer and recently the Ruby language plugin for VSCode I was using was deprecated so I switched to Shopify's ruby-lsp. On the one hand, it's much much more capable than the old plugin: better syntax highlighting, actually useful inline definitions, style hints, etc. On the other hand, it's also way more annoying: there's a bug that sometimes breaks my projects' dependencies so I have to reinstall them, the code completion actually slows me down more than it helps, and if the LSP can't start for some reason (which happens quite often) I get a stack of error popups in the corner of my screen.

On the whole I think I prefer my old setup. All I really need out of my IDE is decent syntax highlighting. I've got devdocs.io for Ruby and most Rails definitions and I know how to spelunk through the Rails codebase for anything that misses. Go-to-definition is handy for my own code but I generally know where it lives, and if I've forgotten there's always ctrl-shift-f or `method(:blah).source_location`.


👤 holri
The hard part is not writing code but to maintain a deep understanding of how it works for a long time. The tools you mention do not help in this regard, maybe they even worsen understanding, structure, format and comments.

👤 Muromec
At some point in time I wrote vue.js in vim without syntax highlight. For a few months. I had to eventually configure it, once somebody asked me if I'm color blind (I'm not).

>So to the devs who don't use these tools, how do you do it? Do you just remember every type and field in a codebase? What does your flow look like?

You don't have to remember every field and type, because you don't work with all the types at the same time. Ones that you work with more often, you remember.

Workflow is something like this: open the file, split to left and right to see two stack frames of the same code path, open another terminal tab, start test watcher. Make changes and see tests fail. If tests don't fail -- write more tests. Then write more code. The usual TDD struggle. In case of CSS, just change it in the browser, then copy back to editor and refactor a but, then check again.

When in doubt about spelling, press shift 8.

>What do you do if you need to look up the definition/implementation of some function which is in some other file?

:open another file and search through it, quote simple. How do I know which file to open? I know and when I don't git grep goes brrr. In theory you can jump to definition even in vim, use fzf to open files faster, in practice, none of that is not the limiting factor.

The limiting factor is iteration cost and the size of your context window.

That all being said, I use vs code now (at work) and use jump to definition all the time, because typescript support is just better in vs code. I think I started using it the moment I had to open more than one repo and switching between them on a regular basis.

Then I get back to my own fun stuff and there I use vim.


👤 throwawa14223
I discovered copilot was disrupting my flow and providing subpar suggestions. Autocomplete and language servers seemed to result in me not knowing the language and libraries as good as I would otherwise.

I almost always have a browser with documentation open on another monitor and while there is a speed hit removing the tools I feel like it improved my mastery of software engineering overall.


👤 atrettel
I suppose this is like a lot of tools in general: you just get used to doing it yourself. People wrote code before tools like that existed, and you can too if you put your mind to it.

I typically just use plain Vim without much customization. You get used to it. I am somewhat forced to use just plain Vim on most things because I often write code on random HPC servers and have no control over what is available. But Vim is universally available, so I got good at the one tool available to me. Vim does have have Ctrl-P to auto-complete a word, though.

I also have books and other documentation available, when possible. Man pages are actually quite good and available on many systems I work on. For C, you can type something like "man 3 printf" to get basic documentation on "printf". This works for MPI too with things like "man 3 mpi_allreduce". I've been pleasantly surprised at times how much offline documentation is available.


👤 0xfaded
I'm one of these, though I use a simple version of autocomplete which only suggests other strings currently loaded in my vim buffers (helps with RSI).

I liken it to spaced repetition. The first time I don't know where to find something I grep, after a few times I start to remember. I have a vim layout with 12 windows, so I have many views into the code and always have space to pull up more without losing context. I genuinely feel claustophobic with less.

> What do you do if you need to look up the definition/implementation

Sometimes I feel "jump to definition" trades immediacy in favor over natural exploration of the surrounding code. I work on a 10 year old mono-repo with 1000s of contributors. After two years I have a good feel for the basic layout, and would say I have a good mental map of the stuff that most affects me. During code review I'm often pointing people to existing implementations that they've just duplicated.


👤 selamtux
i remember when i start coding first time (with note pad), first couple of month i keep pocket book close, then i download the manual (it was 56K times) and it was open all the time. back then memorizing functions from stdlib was a normal thing, but there is a saying, always check man page after you write the code.

first time i use an editor which have auto completion but it works only for same file, it was time saving thing.

then i see real auto completion feature, full function name, parameters, returns and couple of words from manual, it was mind blowing for me.

then i start using eclipse, with one click whole class generation from interfaces etc. one of my friend create its own snippets and it was writing like 3 person, couple of keyword strikes and bamm, whole thing is ready.

then internet become something like air instead of water, constant flow of information, constant needs.


👤 mvanveen
> What do you do if you need to look up the definition/implementation of some function which is in some other file?

At some point, for me, ‘find

-name “*.ext” | xargs grep ’ took over for recursive grep, because the required tools are available on most Unix systems.

👤 dools
I've never used an IDE, perhaps it doesn't matter because I don't write Java. I actually find auto complete annoying in places where it can't be turned off like Google Apps Script or the BigQuery console.

Over the past few years I rarely write code anyway I just use ChatGPT and then edit the code.

I tried using the new canvas/project features last night and I think it slowed me down versus a copy/paste workflow. I think those formats could be good but they're not fast and polished enough and I've gotten used to tricks and hacks for working in chat style.

I've never used a LLM that has actual access to the codebase, so I kind of take chunks of code and put them where they need to be. Even if I have like 6 lines of code and I want to change the logic I past that into ChatGPT and say "change this to do XYZ". Even though that sounds dumb I actually gain massive advantage in concurrency. I can be working on lots of tasks at once because ChatGPT kind of toils away and I'll then jump over to something else and come back 90 seconds later and the code is there, I read it over, maybe diff it from a previous version, then I run that to test it and maybe while that's running I go to a different chat and issue another instruction.

Before LLMs I used vim. When I want to find a function definition I ctrl+z find . -name ".whatever" | xargs grep "function whateverThisIs" and things like that.

grep -d skip "thing"

I copy and paste a lot if I'm using function names, I use a clipboard manager I guess as a sort of pseudo auto complete.

"Then why don't you just use an IDE?" I hear you ask!

It's because I write lots of what you might call "glue code" or "microservices". Lots of snippets of SQL and JavaScript functions that are executed on a queue, and API calls to integrate with things and code that runs on different platforms.

I'm almost never working on what you would call "an app" these days, so that's probably why I've never gravitated towards an IDE. Even when I was working on more monolithic web apps I never used anything other than vim with "set nocompatible" turned on so it wouldn't try to do anything IDE like.

I think what I liked about it then was that I could be just as productive using putty from an internet cafe as I could be on my own computer. Like a doomsdray prepper version of coding.


👤 theideaofcoffee
My bottleneck is how efficiently or completely I can keep the problem I'm working on in my head, not how quickly I can look up a function name or variable or type out the actual code. Really, only the latter is helped along by autocomplete. I find myself with that feeling of my mind slowing down more and more as I get older. When I actually get around to writing the code itself, the problem is mostly solved from my perspective, I'm just dumping out of my head into the editor, that part is easy. Until an autocomplete is wired up with an LLM and LSP which knows exactly how I think and approach problems and remember the codebase, it'll be mostly useless for me. So I don't bother.

👤 sparr0
In my experience, autocomplete/intellisense/LSP/etc is very difficult to get working on most codebases if you aren't already intimately familiar with how that codebase / language / framework / etc works, or someone with that familiarity has laid out exact steps for your IDE.

When I see someone using these features as part of their workflow, I semi-confidently predict that they spend the majority of their time working on a single codebase, such that the time investment to get everything working was worthwhile.

If, like me, you work on multiple different codebases most weeks, it rarely makes sense to even try setting those things up.


👤 pandemic_region
In Java, not having something that automatically inserts imports would be incredibly counter productive. I feel that this is easier in other languages, where you don't need to manually import almost every 'jdk' class that you use.

👤 bawolff
> What do you do if you need to look up the definition/implementation of some function which is in some other file?

I open the other file.


👤 okaleniuk
I use IDE at work but rarely at home.

My design is usually very simple, I don't have to keep a lot of things in mind to begin with. For instance, https://wordsandbuttons.online/ is about 100KSLOC now, but since it's inherently flat, no dependencies, no third parties, I can manage it with a Vim or a gedit with none of the IDE features. My implementation is always in the same file as the call.

I suppose, IDE makes writing harder code easier, which results in tons of saved time, but it also makes writing harder code easier, which results in tons of hard code.


👤 dpcan
I’ve been doing this a looooooong time. And that’s really about it.

Every time a popup or tooltip covers code around my cursor I groan in agony.

I’d probably use it if the tool tips just updated in the bottom right of my screen while I typed or something.


👤 hn30000
CS department at my alma mater was very, very theoretical and we were encouraged to just write code in text editors. After that I got into programming for CAD software which had rudimentary editors as well. Basically I just memorized a bunch of stuff and always had a second monitor with the docs open. These days I use autocomplete but I still largely code the same way, and for better or worse I’m set in my ways — at least when I’m using libraries I’m familiar with. If I’m messing around with something completely new then sure, I’ll make extensive use of autocomplete.

👤 shawn_w
I hate auto complete. The last thing I need is a "helpful" popup of choices. It's distracting and ruins my focus on the code.

I have etags for jumping to a definition on the rare times I need to do that.


👤 pryelluw
I learned to code in a c64 and still sort of program in the same way. I sometimes print (in paper) code to better understand it. Also, I code on plain Vim with no plugins or custom config. *shrugs*

👤 robomartin
For me part of this is a matter of context. The time when I was coding in a single language uninterrupted for months (I think I went a couple of years in one case) are long gone. Once you start context switching between languages, platforms and frameworks, things are very different.

Perhaps the easiest way to explain it might be CSS. If you work with CSS all the time, you retain and recall approaches to solving problems and, more than likely, have developed reusable code to copy-paste-modify. However, those of us who don't touch CSS full time always run into the dumbest of issues (centering and alignment come to mind).

For me modern autocompletion tools are like asking for a capability being loaded into the Matrix. This allows me to switch between just polar opposites as Javascript and Verilog and almost not miss a beat.

Given the right context, I would not fault anyone for relying on these tools. Solving problems computationally isn't about remembering ridiculous syntactical differences between languages but rather about data structures, algorithms, performance and process. If you have a solid background in CS and experience developing software, not remembering the differences between C, C++, Objective-C, Swift, JS, etc., etc., etc. isn't that important.

One caveat: There are domains where you need to have a certain level of expertise without assistive tools. One example of this is mission critical real time systems. Than again, this isn't about remembering syntax and more so about being able to write performant code that is safe.


👤 aardvark179
I use emacs, and although I have LSP configured I switch projects and branches often enough that I don’t rely on it working. Finding definitions is normally pretty easy because code bases have structure, but occasionally can be tricky if the method is inherited, or overridden by subclasses, but that sort of thing sticks in your head after working with a codebase for a little while.

I think co-pilot is the more interesting example you give, because my answer is that I will not use it unless I could do the job without it. For example: yesterday I was refactoring a bytecode interpreter as the core loop had grown so large it was causing a performance issue. Solving this required getting the size of the method containing the inner loop back below a threshold. This isn’t something an IDE’s “Extract method” refactoring can do automatically because there is mutable state that needs to be passed in and out, and if I didn’t already know how I wanted to do it, would not be something I could easily check the correctness of co-pilot doing. So you sit down and think. What stages will you have to go through to extract and change this code? You come up with something that will let you validate the idea and then refine it, and you have tests, lots of tests, and some degree of intuition so that when you see a failure you can guess the thing you might have missed.


👤 dmmartins
I get distracted by auto complete and they usually stay in front of the code, so I can't read it. I find it annoying when I'm pairing with someone that uses it and the auto complete/type hint/whatever pops up and covers most of the code I was trying to read

Working in a code base every day I end up creating a mental map of the code and the data, so it's not hard to find stuff I'm looking for. When that doesn't work, a global search or find/grep helps.


👤 kristopolous
Auto-closing tags. hate them. I go to encapsulate something in quotes and it just tosses a closed quote right next to it, incorrectly. They perpetually make the wrong move.

All the "smart systems" are equally annoying. The auto-comment generators are just trash. They just add noise like this:

   # Object receives something
   object.receive(something)
I see this stuff in code review, just did today, I just ignore it now. Garbage added by the IDE, whatever.

And then there is the "smart indent" systems that seem to always guess incorrectly.

These systems are like a 4 year old trying to help you wash the dishes. I don't know how you people deal with it.

I coded for years on a line editor (ed). It was probably faster coding then whatever I'm using today. That thing was basically gestures moving at the speed of thought.

grumble grumble, kids these days.


👤 imsnif
When I tried to get into programming as a teenager, I opened a graphical IDE and was immediately overwhelmed by a barrage of menus, popping windows and tooltips. This led me to believe programming is not for me. In later attempts I used vim (back then that's what people used to recommend those starting out with perl) and felt right at home.

These days I still use vim (almost stock) for everything (right now mostly Rust). This is totally anecdotal, but I'm usually more productive than my teammates - mostly because of the initial hurdles of getting into a new codebase or parts thereof. I don't have anything to set up, I just open it up and grep my way to success.

Every now and then I try to open an IDE and force myself to work with it a little bit just to be sure I'm not missing anything. The visual overload and lack of advanced editing are just too much for me. Going back to vim is always a breath of fresh air.

I'd sooner use nano/notepad.exe than any sort of graphical IDE (though I prefer vim).

I'm not saying this is the best way, I definitely do not recommend it to those asking me how to get into programming, but it's definitely the best one for me.


👤 agentultra
I find that I don’t use heavy IDE features much.

I just use a TAGS file for definition lookups. It’s fast to generate. Every editor worth its salt understands the format. It’s fast.

It’s perhaps slow but I do tend to use my own memory instead of autocomplete. As I use a module more frequently I tend to recall it from memory and know what I want ahead of time. So eventually I get faster than autocomplete. And bonus I get to know the codebase.

I find I make up for the initial slowness because I do most of my thinking before I hit the keyboard. Sometimes the autocomplete is faster than I can type but often it elects to select the wrong thing by default and it takes me more willpower and key presses to select the right one than to simply type what I want.

Slight gains at the keyboard don’t equate to much for me.

Although if you watch my streams you can see me smooth brain my way through stuff without much in the way of IDE tooling. Often when I’m streaming I’m programming off the cuff, chatting with folks, and generally more distracted than I usually am when programming alone. I also look up documentation manually a lot either because I want to show the stream or because I’m so distracted I have a memory like a fish.

Over time though I prefer to internalize and learn than to rely on tools to do the thinking and recall for me.

I don’t really use AI tools. I find reviewing the code mentally exhausting and tedious. I prefer to simply write the code I want rather than try to clumsily tell a robot how to. Plain language is sufficiently vague for conversation and too vague for programming tasks.


👤 sethhochberg
I had a data structures / algorithms professor in college who would occasionally ask us to write C++ by hand, on paper, during exams.

Syntax wasn't really graded, its forgivable to make trivial syntax errors on pen and paper. The questions never covered more than a few dozen lines of code. But doing it this way forced us to really actually hold an entire small problem in our heads instead of just whatever slice of it the IDE was helping us focus on at the time and I think developing some of that skillset ended up being hugely useful to me when I started my career and was jumping into codebases far larger than I'd ever navigated before.

Jump-to-definition and search for symbols in RubyMine/IDEA are some of my most used tools today, but I think I'd probably be a worse programmer if I never had to develop the skill of working without them to a certain extent. I'd encourage everyone to give it a shot next time you have a few minutes to sharpen the saw. Grab a yellow legal pad and write a little toy parser/lexer for a toy programming language you just invented.

FWIW: I also love printing out diffs for nontrivial code reviews and marking them up with pen and paper, particularly big SQL views.


👤 SamWhited
Find definition of Foo():

  grep -IR "func Foo("
Show uses of Foo():

  grep -IR "Foo("
Hmm, what were the methods in that field again? Open a split pane in Vim and scroll down in the second pane to where the field is defined. Also I pretty much just have the standard libraries of my most commonly used programming languages more or less memorized and keep the docs open in a separate window alongside as well for when I don't. And of course in a sensible language that actually gives you feedback (I'm aware some languages are more or less strict about this and it's not an option for everyone): when I try to build it, it will fail, indicating that I've done something wrong. This is okay, use the build loop and embrace the build errors.

*EDIT:* updating to address "CoPilot" specifically, as I don't think it's the same as the other things on your list. I have reviewed a lot of submissions that were written with various AIs and all of them without fail, this is not hyperboly, all of them were just bad (I'm sure someone will say that if you just use it for a 1 line error tweak it will be fine and what could go wrong there? And sure, probably, but if that's the case you're not getting any benefit from them so that's not what I'm interested in). The code was worse than a human would have written it, there were subtle bugs that no one had noticed because they were trusting the AI, etc. just don't use them. They're not ready, they may be speeding you up, but they're slowing down whomever is reviewing your code. It's a serious disservice.


👤 lieks
I used to not use any of those tools. In C, I split my source into logical modules, and added a short module prefix to each function, to make it easy to find.

Later, I found out about ctags and started using it; but it's not that useful for autocomplete. I kept to my old naming conventions: one verb whenever possible, plus any prepositions (is/has/etc.), noun if applicable, and module prefix.

This works well for the programs (not libraries) I write. Libraries have a different set of design considerations.

My function names end up like:

    memalloc (mem module, alloc verb)
    print (no module, print verb)
    gccollect (gc module, collect verb)
    vecappend (vec module/noun, append verb)
    Vec (module/noun)
    render (static function, render verb)
Most functions should end up private (static/not exported) anyway, so exported names can be short and still unambiguous.

In languages that have namespaces like Go or Python, I use their own namespace facility. I like to avoid the need for underscores or capitals in names so I don't have to press shift to type them, but some languages (Go) make this unnecessarily hard.

Eventually, when I started working in large Python and Java codebases written by others, I had to get an LSP plugin so it would take me to the correct definition. Ctags doesn't know about overloads. And some people don't care if they put a function in a logical place or not.

My editor's plugin doesn't have autocomplete, but giving functions a reasonably-sized name (and having two code windows open side-by-side) solves that problem.


👤 p4bl0
Wow, I didn't think I'll read something like this before years. It's a bit sad to be honest. I'll give the same advice I give to my students: force yourself to code using only Nano as your editor. It has plenty of editing features (line numbering, syntax highlighting, auto-indent, multiple buffer, keyboard macros, etc.) and those should be more than enough if you do known how to program. You're of course allowed a browser for the documentations and a shell to interact with other tools: interpreters, compilers, git, etc.

Just like it's good to be able go somewhere by actually reading a map and following street indications if you don't have access to digital map app and/or a GPS, it's good to be able to code without depending on tools that actually do the work for you. It's true for an IDE if you don't know how to navigate source code or how to build your project without it. It's even more true for stuff like copilot which actually write code for you…


👤 jmward01
Embrace the diversity. Some people use these tools, some don't. What matters is that you build something great at the end. The only people that are 'wrong' are the ones that mock those that use the features and the ones that mock those for not using them. Probably the best programmers are the ones that can adapt continuously to the new tools out there and find, and use, their strengths.

👤 artisanspam
I primarily write code in a DSL which has no good FOSS LSP implementation. If I’m writing this code on my personal computer I’m out of luck. My employer pays for a language server that requires a license.

There are a non-negligible number of my coworkers who don’t use the licensed LSP implementation and they write all their code in vim – or worse, gvim through a VNC. It’s very easy to tell that their code quality is worse.


👤 specialist
For IDEs, I use Jetbrains and some VS Code.

Autocomplete mostly pisses me off. Most of my completions are triggered accidently. Whether it's because of me, the trackpad, or my crappy keyboard, I dunno.

I want the suggestions off to the side, not in some rando pop-over that's always moving around. So distracting.

My alternate UX notion is for the cursor's focus to always remain in the middle of the editing window. The content (source code) would scroll up and down "under" the cursor.

Then all those inlines, suggestions, autocompletions, popovers, whatever could always appear in the same location. Not dance around or try to fit where there's no room.

Next, since I'm polyglot, I spend a lot of time splunking javadoc (or equiv). I want some kind of hybrid between suggestions and abbreviated javadocs.

--

There is one onerous (to me) task which chatgpt excels. My new tool injests SQL. I'm assembling a corpus of tests, scrapped and copied from all over. Whenever my parser fails, chatgpt helps me to identify the correct dialect (grammar specification BNF) to reference.

For straight coding, I mostly use chatgpt to get oriented, get started. For common tasks I haven't done (any time recently). Like how do today's yoots do command line parsing? Replacing stackoverflow, more or less.

Otherwise, my current (hobby) project is a new take on an old problem. (Re)Invention and innovation. Chatgpt is sometimes helpful (to me) for brainstorming or validating a notion. But I'm too ignorant to know how to get chatgpt to help me create a new (to the world) thing.

If I was doing CRUD or game development, I'm sure chatgpt would be very useful.


👤 taeric
At the start, isn't this a bit like asking how people navigate cities they live in without constantly checking a map? The various strategies different people have will be remarkably varied. And there will be blind sides for many people. Hidden paths that some people know and always use, as well as parking spots that some people always try to get.

Moving beyond that, it isn't like LSP originated the "go-to-definition" feature. Indeed, this is one of the things many of us like about Emacs. You can literally jump to the definition of most any function currently in use by the environment. Can even edit it and have that edit immediately open.

But, moving back to my original line. The answer is people work in different ways. Is why some folks get really good at typing on a keyboard. Most people probably are not fast typists. But that doesn't necessarily mean the advantage a fast typists has will be realized in any actual gains.


👤 graypegg
I use an LSP and every IDE feature in intelliJ for typescript, Java, and anything else well-supported by jetbrains... except Ruby.

For me, Ruby's standard library tends to use names for things I would guess first, and the way people build things in Ruby feels natural to me. Any sort of LSP feature is nice obviously since it's never in the way, but when I end up trying Solargraph or RubyMine I end up noticing I'm just not paying much attention to it. The only places where I end up reaching for it is mass refactoring, like big renames... which are tough in things like Rails projects where files need to be renamed and pluralization matters.

So for me, it's the ergonomics of the language. That's probably mostly related to hours spent with it of course, but I think everyone has some specific environment/language/style that lets them compress the current state of what they're working on in their head better than anything else.


👤 popee
I use ratpoison tiling wm with custom bindings, it's kind of tmux or screen for Xorg where you stack apps for example firefox, vim, ssh, tmux/screen, terms. Anyway, it's up to you how you search ctags, man, grep, web, etc

This setup is agile but still not as fast as lsp or copilot, but I prefer learning and remembering over speed, personal taste :-)


👤 cladopa
I would say advanced programmers were using some kind of autocomplete way before Microsoft popularised it.

The concept of IDE was invented by lisp machines, and emacs inherited a great deal of that functionality, but without the visual IDE. Great programmers were using shortcuts for accessing documentation at incredible speeds. The go-to-definition was there although limited to supported languages only, usually lisp dialects.

What Microsoft did was popularising it, standardising for different languages and making it easy to use/visual-graphical interfaces and destroying the competition the MS way, like Borland.

I would say, except copilot, all those features existed 30-40 years ago. It was just a pain in the a$$ to set or very expensive(Lisp Machines IDEs) or difficult to pirate(very important for Microsoft success).

Copilot can be replaced by competitor's products, like Claude. I use them outside Microsoft ecosystem. I use my own automatic system to access the AI.


👤 flemhans
I programmed by hand for 25 years out of stubbornness, and finally installed JetBrains. Just do it, it's such a time-saver.

👤 knorker
Can you drive a car with manual transmission?

If you can, then do you feel helped by automatic transmission? I don't. I feel like too often the automatic transmission makes the wrong choice. It doesn't feel like more work at all, and allows for much better control of engine braking.

(You shouldn't be using your other hand to hold anything while driving anyway)


👤 tmulcahy
I usually code with VIM. I work in many different languages and repos simultaneously. Python, TypeScript, C++, Kotlin, etc. Sometimes I need to ssh into a server and code there because I can't build AOSP on my Mac laptop. I sometimes find autocomplete helpful, but I can't be bothered to keep it working across all of these environments.

👤 masternight
So, Autocomplete, Lang Server and Copilot.

I don't use any of those, and I've never felt the need for them really. Is Make and Vim not an IDE?

None of those existed when I started to code at my first dayjob and I've never really seen the value in them.

I find it interesting you think that go-to-definition isn't possible without a language server. I was doing that long before lang servers existed.

When I want to look a function signature up, well there's two ways I do it.

1) vim + ctags and Ctrl-] will take you there (usually, sometimes it gets confused).

2) grep (or nowdays, ripgrep) the codebase for the name of the function (in another window).

As for remembering what is where. Good organization helps. After time I tend to develop a mental model of what is where and I'll just find myself popping over to the other terminal and opening a file in vim to find what I need.

You can take syntax highlighting from my cold dead hands, though.


👤 lhamil64
At work we use very niche languages that don't have language servers or really much support in IDEs in general (people have internally written syntax highlighters but that's about it). So I can't Ctrl+Click to jump to the definition or anything like that. Typically I use VSCode's directory find feature (or CLI tools like grep) to just search the codebase. This does mean weeding through results in comments and such, and makes it really annoying for non-unique variable names.

As for things like type hints, I end up switching between tabs or splitting the editor to view the definitions. Although that hasn't been a huge problem for me since the types of these languages aren't as robust as more mainstream languages.


👤 xgkickt
I have to use VS for work and Intellisense can be so annoying. Too slow (I've already completed the word), or unhelpful. Example: Accessing elements in a 3d vector, having already typed "var." it pops up with the options, x, y, or z, every time. It's not saving me any keypresses, especially after I've already accessed some elements so I know the members of the struct. Also, how about matching to variables or types from the local scope outwards rather than offer something in a system header not present in any preceding code.

So I have it disabled and just search for things (another thing VS can go complete blank on), keeping the relevant file open in another window for reference, which means I also get to read all the comments in the code before using it.


👤 kussenverboten
Just take a pen and a sheet of paper and see how far you can get.

👤 noufalibrahim
I've recently picked up using lsp now that a lot of my work is in go. I have co-pilot but often forget that it's there and don't use it much.

Generally, I have a hill to climb with a new code base. I get the ideas into my head and then rely on that rather than tooling. It's how I've always worked. I'm very comfortable with my editor so it just does what i think and i don't have to expend effort to translate my thoughts into keystrokes.

That's basically it. This Blog Post by a friend of mine on important editor skills to master is a good read on effectively using an editor https://info.pagnis.in/blog/2014/05/06/10-actions-you-must-i...


👤 msie
Yes, lots of memorization with an occasional Google search. When you program a lot you just remember things.

👤 bigpeopleareold
Random thoughts on this topic:

- Years ago, I didn't use anything. It was just me, Emacs and a few packages. I surely knew about IDE features, but didn't bother. But I did get frustrated to have to look up things every time when I forget something. Autocompletion is an improvement and seeing docs fly up on a function helps a lot. But it's one part of the picture where the computer aids me...

- case in point: rg or ag are fantastic tools for searching through codebases. I use go-to-definition too if I can. However, I usually can find pointed references to fuzzy ideas about things much faster than co-workers who don't use rg, because regexing a codebase is much simpler than tediously running through files I am not familiar with to get a quick answer.

- autocomplete is useful when I don't know the language and helps to spell correctly. It does take me away from learning a language, but I don't do a lot of coding (hope that changes in 2025!)

- when I write Python, I don't really need tools as much. I pull up docs more. I have pylsp installed and sometimes when it is off or it can't boot for some reason, I just grumble and continue to do things without it. The same with bash. I am good with python but stink with bash, but still don't use LSP at all with bash.

- I still have some odd fears that since I don't use dedicated IDEs for most things, I will get disrespected when it is relevant for career progression. This is not without merit - sometimes computer-assisted tools can help with certain tasks much faster than others. We shouldn't measure based on individual tasks, but if you are getting constantly stuck on trying to finish something but the bottleneck is your chosen text editor/environment to convey ideas, it can look negatively.

- please, no copilot! I already feel like I lean on search engines too much to answer my questions. I know I become better when I enrich myself with general knowledge on a topic. It doesn't answer everything (thankfully search engines are there for that and don't want the quality of sites fall by the wayside because of copilot), but I imagine I would not be so swift on the types of problems I solve if it weren't for deliberate documentation reads and discovery.

- I am improving my understanding of Lisps (common and emacs). I feel like there is a different experience working in these. The typical IDE tools feel different given that all these tools can be used to interact with a running environment instead of using something that just primarily analyzes source code. I would probably fall back to my old habits when I am comfortable, but it is fascinating at least to me how the tools fit together differently than in "normal" languages.


👤 crabbone
Due to how my job is defined, autocompletion (the kind that comes with LSP) is usually not an option at all. In the context of my job, the largest part of my effort goes towards RCA (figuring why something doesn't work) in a system mostly not written or designed by me.

This means, that most of the time I deal with a system after it was deployed, often times in a distributed system with most of it only accessible remotely. So, the aspects of my tools that I value (over autocompletion) are integration with shell / terminal, integration with debuggers / tracers / profilers, ability to quickly search / patch files in any format.

Typically, if you look at my monitor (when I'm actually doing something), you'll see Emacs running ansi-term with tmux that shows a bunch of buffers with shells in VMs in different corners of the world, database interactive clients, interactive debuggers, interactive interpreters, vi with multiple tabs open, multiple journalctl -fu xxx buffers, or perhaps kubectl logs -f xxx buffers etc. and outside of tmux some Org buffers with lists of tasks or text that I use to export to JIRA markdown.

(I think my setup would make for an exciting hacker representation in some sci-fi movie! It's all green letters changing rapidly on black background in many small adjacent boxes)

Even in this context, there's some word completion available (eg. in shell, or in Emacs just trying to complete the word by finding similar words in the same buffer), but usually by the time I actually need to write something new (rather than add breakpoints or investigate in some other way), it's crystal clear what needs to be written, and I don't need to leaf through pages of autocompletion to find the right word.

---

Now, while most developers don't spend that much time figuring out why their software doesn't work, I still think it's a significant portion of any developer's work, so, simply from the standpoint of how much time you spend in what environment it might make sense to go for a tool that's better at editing text than a tool that has better integration with LSP.


👤 jebarker
I don't use most of these features other than go to definition. I find popups deeply annoying. I've tried using other features such as autocomplete but I've never found it very useful. I think it's due to the type of work I do. I rarely write lots of new code and instead spend most of my time debugging existing code and making relatively small changes. Go to definition seems to be the only navigation feature I find useful. However, I use a debugger almost continuously to monitor the state of running code and I have a similar question as you for all the developers that never use a debugger - that seems weird to me now.

👤 thesz
First, surrounding your code is other code that very probably have a clue on what you should do. You do not have to go at the definition to see what to do.

Second, for one written/changed line I have read, perhaps, couple of hundredths of lines of code. This results not in a "fBeggy is a field of a class CBaggy" kind of understanding, but "the general approach to solve problem like this one at hand will be such (see this part) and such (also see this part)."

As a software support engineer, I have twice as low yearly output of (real) LOC (11.5K/y) than is expected from software engineers at, say, IBM. Mostly from the need to read substantial amount of code.


👤 analog31
I find myself going back and forth about whether I want all of that stuff. Not having to look up a function template is handy. On the other hand, having my code bouncing all around, and obscured by random pop-ups, is distracting and eyestrain inducing. None of it is touch-screen friendly, though I admit that it's reasonably well designed for keyboard shortcuts.

I'm on the fence about copilot. It's like today's story of Julius, an assistant who is beloved by management, but whose work demands attention and must be corrected. Doing a Google search for something is less "efficient" but I need to take frequent little mental and physical breaks anyway.


👤 ThinkBeat
Back in the before time my computer science exams¹ that lasted around 6h-7h We had to write the code requested with pen and paper and no reference sources or anything else.

and yes the code were to be written with the expectation that whoever graded the paper could run it and it would work. (I dont think anyone every tried typing it in)., and none of the questinos requred short answers.

(Well the ones where programming was a bit part of it. Others were math, where again you hand wrote it and you had no access to any reference books)


👤 bfung
Spicy take: I write minimal but easy enough code to follow that there’s no “flow” needed. And by extension, no need for anything except a text editor.

Easy to say, takes a lot of practice, focus, and knowing common concepts across all languages to execute on.


👤 65
Newer fancy things like code completion are a little faster, but the thing I care about most in my IDE is if I can command+click for type definitions.

For example, writing Python scripts for Fusion 360 modeling is almost impossible if you aren't able to find all the methods and type definitions as Autodesk's documentation is pretty terrible and doesn't list most methods.

If your IDE doesn't have type definition support, being productive with certain APIs with terrible documentation is impossible.

If it's all vanilla code, then this isn't as much of a problem. So the need for better IDEs comes with more complex code.


👤 SigmundA
I started professionally programming using VB back in the 90's, I remember how amazing it was at the time to use an IDE with autocomplete and a visual debugger coming from just doing basic on say the Commodore. I was never a C or assembly programmer, I understood it but everything I wanted to do I could do much faster in a higher level language in an IDE.

This was back when Windows was finally getting good (Win95) and I was not familiar with Unix at all. All of this seemed like the obvious progression from text base UI's to GUI's.

So for me it has been very natural to use autocomplete and expect to just attach a debugger and inspect running code and even modify it (VB allowed edit and continue) which is still a rare thing today that I miss.

Also using a mouse to move around the code base and inspect it just like using a GUI to use the computer. Because of this I have never developed a strong keyboard only ability, I expect a mouse to be available.

I remember getting into web development and having to step backwards into a language that wasn't really typed and no real IDE's that could autocomplete an interactive debugger, back to print debugging and text searching. Eventually the browser developer tools caught up but the JS language was pretty difficult to accurately autocomplete and navigate / refactor properly at a code level with an IDE.

Was fun to watch all the JS devs get excited over Typescript because autocomplete and refactor now worked reliably. For me having a language with real types the IDE can understand was the way it's supposed to be.

It seems like it's how you got started that determines your preference. If you were a Unix guy you liked the command line and TUI's and everything was about wrangling things at a text level, everything is a file and just a stream of bytes. If you were a Windows or Mac person then it was GUI's and mouse interaction and it was more about widgets and objects and IDE's.

I can appreciate both sides, I would like to be stronger in the command line and keyboard but how I got started strong influences the tooling I prefer and I am sort of set in my ways now, I suspect that is pretty typical.


👤 elric
I use eclipse for most of my Serious Work. With most "clever" features turned off. The kind of code-completion that lets me browse a list of partial matches is very useful (e.g. was it foo.bar() or foo.baz()?). Other than that, I like to do my own thinking. I enjoy writing software, not maintaining software that was generated by some tool.

Do I remember every type and every field? Of course not. But my codebases are structured. There are naming conventions in place. I generally have an intuition of where to find things. And of course there are many ways of searching for stuff...


👤 camgunz
This comes up from time to time and I always struggle to succinctly make the point I'm about to try and make again here:

Your brain is a good natural limit on complexity. I'm not saying there aren't goals that merit tools to manage complexity beyond what your brain could, only that you should be extremely reticent to unshackle that monster, because it's more likely to eat you than do your bidding.

Or more practically (and maybe more of a polemic): if you're maxing out the capabilities of your IDE on an average project, you goofed! We built postgresql, sqlite, Redis, Linux, Go, etc without IDEs.


👤 pSYoniK
I've built a few small personal projects using Vim with NERDTree only in C#. I keep doing this every few months (small means the solution has around 4-5 projects and it performs a few clearly defined little functions) and it is really is both helpful and interesting to realize how many things we take for granted, but how great it feels to better understand dependencies, which nuget packages are needed, version compatibility issues and many other things.

I also end up better knowing and remembering any new classes and methods because I have to dig through the reference documentation for each of these things.


👤 rich_sasha
One key upside of Emacs for me is that you can open 3+ screens of code on one monitor. It compensates somewhat for lack of IDE features - I can literally see a lot of the code the IDE would otherwise be completing for me.

👤 qazxcvbnmlp
One thing that’s missing from this discussion is the level of experience of the user and the type of projects they work on.

How long you have worked in a particular language affects how much you will be looking up function definitions.

Lots of other people working on the same project with loose standards means harder time assembling a mental model of the codebase.

Someone with cursor asked to program in a new language may be like “ah ok whatever sure” vs someone with vim might be like “it’s unreasonable management wants us to use these new age tools X works just fine” and then say “vim is so fast” in the same sitting.


👤 nottorp
Sometimes you don't get a choice.

Some embedded ish IDEs, ssh-ing to a remote machine where you only have text mode etc.

You'd better keep that part of your brain that can code without autocomplete in shape, you never know when you may need it.


👤 koinedad
If you’re changing languages fairly regularly it can be more helpful, but if you’re in a comfortable language it’s pretty easy to memorize the most common functions/methods etc.

I recently had to switch to a project in Ruby and the LSP was not working it was frustrating but I can’t say that when it started working the next day that it helped me that much more. Maybe like 10% improvement?

Command F, command shift F in most IDEs to look up the definition if LSP isn’t working just search for name and append the class, method, function definition syntax. Like “function getUser” or whatever.


👤 bdcravens
Earlier in my career, I would often turn those features off. It was the late 1990s, and computers were much slower, and as a result, I didn't like the lag that some of those features would cause. As such, I learned to work without them.

These days of course computers have no issues. However, I've moved to a completely Docker Compose driven workflow, but for various reasons, I've run into issues getting LSPs etc working correctly. From time to time I'll take a stab at getting it working again, with some success, but rarely do I have that kind of free time (I typically work on small teams)


👤 t-3
When I can't remember something, I look in the documentation or at the implementation. For functions I use often, I remember what arguments they take and what they return, for others I just look them up as needed.

👤 ooooooooldguy
After 40+ years of programming, you tend to retain some things. I started out in 1984, so that means in 40 years, "me" of today will be in the year 2064. I cannot fathom what coding will be like then. But if I compare today vs. when I started, there are remarkably few differences. GDB has been my debugger for decades. The IDEs are better, but the UNIX CLI is still essentially the same. Bells and whistles don't help you solve problems, they just give you something to tinker with in between the real ideas, IMHO.

👤 ustad
A question which I’m being asked more frequently as time goes by. Something that I just thought of is that i’ve worked mostly on long term projects which i’m usually the main architect. I know how the systems work inside out so I don’t really need IDEs to help me out with showing me where stuff is or being an encyclopaedia of function names, parameters etc.

Its a similar story with frameworks, those who create systems which are mostly frameworks wired together and those who strive for minimal dependencies. You can guess which camp I’m smoking my pipe in.


👤 lmm
I use a concise language that I know well. When your language doesn't have so much boilerplate junk, you don't need an AI to generate it for you.

Try working in a really concise language, e.g. an APL-family one, for a bit. Once you get used to it you might take the style back to other languages, it's possible to write fairly concise code in most languages if you actually try. See e.g. https://github.com/tlack/b-decoded/blob/master/b.c


👤 Fizzadar
Long time sublime user, always has autocomplete off as it’s more a distraction than use. Recently started using LSPs for the inline error/warning checking but avoid things like go to definition - search works just as well in my experience and is faster.

See lots of comments here about code organisation and developing a deeper understanding of a codebase and I could not agree more. At least for myself not having all these functions gives me a deeper understanding of the code. I’m probably slower to onboard onto a codebase but I bet long term have higher productivity on it.


👤 mfranc42
For C++ projects I use a language server to jump around within Emacs. For a Linux kernel which is my day job, I just use git grep, since I couldn't make the language server work across multiple architectures at the same time and plain old C is simple enough for that. I have never used auto completion, so perhaps I don't know what I am missing. At least to me, coming up with an idea how to do stuff is more time-consuming than writing it down in an editor.

👤 innocentoldguy
I've never used an IDE to write code, though I have tested a few out on the recommendation of others. For 30+ years, I've only used these plain-text editors in this order: Vi, Vim, NeoVim, Emacs, Kakoune, and now Helix (I used Vim for most of that time).

I guess I keep everything in my head and use reference materials when I forget something.

IDEs bother me. I enjoy working in the terminal and have always found using a mouse while writing code annoying. I also dislike having tabs, buttons, menus, drop-downs, pop-ups, etc., in my way while I think and write code.


👤 keyle
There are still a lot of developers out there that basically are at the hammer and nails level of programming. They use a basic editor with basic syntax colouring and when they write broken grammar, the editor just misbehaves telling them they've typoed something.

Many still use rg and fd or fzf outside or within their editor and are anti IDE.

I think ultimately they do waste time, particularly they see refactoring as a big 4 hours job when people using intelliJ and other proficient IDE will see it as a 5' job.

That said, have you every felt, that using all the bells and whistle, half the time you're being impaired by them? Auto-complete nags you, copilot is completely off the plot and spewing tons of stuff all the time.

The key, I think, is to have all the bells and whistle but have shortcuts to turn them on/off. I have auto-complete only drop down on ctrl+space shortcut, not automatically. And for copilot, I have ctrl+cmd+c for turning it on or off.

That way I can free flow type code as I think of it and get the tools to assist whenever needed. It's the best of both world. The IDE as clutter free as possible, and all the tools at a finger tip.

But renaming symbols throughout large projects without an LSP? Nah, been there, done that, for decades, and I'm glad that's over.


👤 memsom
I think this is very much an age dependent thing for me. When I started programming, there were no LSPs. There was not even any real code completion. I was using the Delphi 1 IDE in my first job and that didn't even really have any type checking till you compiled.

I think Delphi 3 was the first version with basic completion.

I do feel like I have suffered and become a little too dependent on LSPs/AI over time. But it is easy to see why when they can basically write your next line for you with quite a lot of accuracy these days.


👤 Kapura
I did a lot of work in unassisted vim when I was in university, and I would say the answer is twofold:

- you become a proficient user of tabs in whatever IDE or text editor or window manager you use. you open up header files (or collapsed source files, depending on the language/IDE) and reference the API you use.

- you get better at naming things. You don't need to guess the name of any specific API, because it makes sense within the context of your codebase. I believe this makes you a better programmer.


👤 itronitron
I've learned two languages using just a text editor (VI or Notepad) and found that it really helped me spot typos and syntax issues early on. I keep a browser open with tabs loaded for referencing language/package docs and referencing examples. Compiler errors literally tell you where your mistakes are, which is great for learning a new language.

I definitely recommend IDEs for navigating large codebases at work, but I feel like autocomplete has gotten much worse over the past ten years, as it tends to be slower and less concise.


👤 01jonny01
Up until a few years ago I was still using notepad.exe and uploading via FTP and managed fine...fine as in my business made $700k in a year and my programming was ability was poor.

Now I use VSCode and pushto github. Has it made me any better? A little I guess. The real step change for me was ChatGPT. For scrappy slow learners like myself it allows me to x10 my output.


👤 TheCapeGreek
PSA: No matter how good you are, please don't do this if you're working in a tech stack you are not familiar with, in a team with people who are experts and are using fully fledged IDEs.

There will be inevitable ultra-basic mistakes, especially if you're also not familiar with testing the code you're actually writing.

I say this as a specialist using an IDE and having had PRs sent to me that weren't even syntactically valid, because the developer was not using an LSP in a language they were not familiar with.


👤 anonnon
Am I the only one paranoid about LLM IDE integration like copilot stealing your code and using it as training data, even if there's a privacy policy that denies any such intent?

👤 ccanning
Bad coders are bad coders. It has nothing to do with an IDE or features that streamline the process. Code Organization takes a higher-level of intelligence or skill that most people rarely develop without a solid mentor. If you have an organization with poor developers, then you’re not stepping up and using code reviews to mentor or taking time out of your day to educate. Most likely, your code is also not that well-written either or they would learn from that.

👤 RadiozRadioz
I've found that regular non-language-aware autocomplete is sufficient for me, plus recursive greps through repos. Referencing my app's data structures in another editor window is useful too.

I use JavaScript and Python. Because they are dynamically typed, I never had full confidence in IDE-like tools in my text editors. I see those languages as flimsy foundations to add IDE tooling to, I would always experience situations where the editor had no idea what type something was. So I stopped bothering entirely.


👤 o11c
Java is the only language I've ever met where an autocomplete might be a net positive, since the ecosystem is full of excessive verbosity. I'm not confident about that, since I don't write anything in Java if I can help it.

For other languages - typing is never the limiting factor, and actually reading the docs is better than praying that your IDE gives you something meaningful. For languages with a working REPL (or even a typo-detector) you can use that if you really need to introspect.


👤 dotancohen
Just about a decade ago I switched from VIM to an IDE with auto complete. For me personally, typing it all out made me far more intimate with the code, but more importantly it forced me to be very intimate with the language.

Today, at the other extreme of having an LLM actually write entire methods or sometimes classes for me, I do feel that I have less of a mental model of how my software is designed. Ostensibly I still "wrote" all of it, but it's just not in my mental cache.

Or, that's just age ))


👤 gosub100
> Do you just remember every type and field in a codebase?

I type 'make' and let the compiler show me where the definitions fail. Often it will suggest the valid options. Opening the header in another buffer or window also helps.

I value semantic correctness first and don't get distracted by syntax errors if I'm in deep concentration. Conversely, I often make small changes when I anticipate a compiler error so I will know exactly where it came from, fix it (often by trial and error) and move on.


👤 lynndotpy
It depends on what I'm working with.

A huge 100k LoC codebase? I'll happily boot something with an LSP. But it's very annoying and gets in the way. I hate when the context for my keystrokes is an autocomplete window, but it's worth it if I need to call a method with fourty arguments.

But when I'm writing code from scratch, it means I know what I wrote and what I'm using. If I forget, I usually just go back through the code.

Pen and paper is very useful as an extra scratch space.


👤 vinc
I have code completion in vim and I try it every few years and sure it can save a few key strokes but the habit of using it never stays with me.

I think I just learn the code base and build a mental model of where everything is and it works for me. I spend more time thinking about how to organize my code well than to actually type it in my editor anyway. It probably helps that I'm working on Rails apps so there are strong conventions about how to do things that makes this easier.


👤 divbzero
For most of my projects, the key value I can add is in understanding business needs, translating them to technical requirements, and ensuring sensible choices of data structures, APIs, libraries, etc. Rarely is code generation the rate limiting step.

I do find autocomplete and language servers useful for avoiding typos, but typically there is already some form of compilation, type checking, or linting to ensure valid code.


👤 englishspot
I have NeoVim open on one terminal and just the console on another. I just run the linter/auto-formatter/compiler directly on that second terminal after I write in the first. if I need to remember a type/method/class, the default suggestions (ctrl+n in INSERT mode) or a simple grep are usually enough.

is this the most efficient way to code? probably not. but it involves zero yakshaving, which I no longer have the patience for.


👤 k2so
In one of my earlier jobs a few years back, we were training deep learning models on VMs with GPUs, back then the tooling was not as extensive (vs-code did not have the remote ssh then) as it is is now.

So, we would use SSH into the VM and do our work. This also involved a lot of debugging of code through vim since it's quicker to make in-place edits and re-run experiments, this taught me a lot on effective debugging and writing code for the VM


👤 benreesman
I use the tools when they’re available (and performant and stable), but they aren’t always.

Pretty much anywhere you’ve got grep, and if you’ve got grep you can find anything in a reasonable amount of time.

The tools are great when they work well, but if you become too dependent on them you wind up at the mercy of other people in certain situations: notably when the tools are broken and need fixing.


👤 xuhu
Same as driving in the city without Waze. Replying to an email in German without Google Translate. There are a bunch of reasons, one of them is because I like it.

👤 anonzzzies
Some languages like c/j/k/perl/vanilla js etc I have no issues doing without these tools: they are usually more an annoyance than doing anything useful anyway. For verbose languages or environments where you are basically gluing libraries together, I do like these tools. Cannot imagine how you comfortably spelonk the trillion npms you get thrown in your lap in that project you got handed.

👤 sgarland
I use nvim. If I need to look something up, I use Telescope, which pops a modal up in the current buffer. Type the first few characters of whatever you’re looking for, and get a preview of it in the codebase, as well as the path. If I want to, I can then open that file for further investigation.

I personally don’t like the surprise of autocomplete, or of anything popping up on-screen that I didn’t ask for.


👤 sinuhe69
If you just used a library for a few times or new to the language, LSP is indispensable and immensely helpful and productive. But after working with them for a long, you automatically memorize things and don’t really need them anymore. Until you work with a new library. And nowadays, library and frameworks make the heaviest burden of the daily programming task, not the language.

👤 evjan
”In my experience, the stronger programmers don't use an IDE and also have no problem producing code at the same speed as IDE users. I also find that the code produced with an IDE is lower quality. I have no idea why”

Zed Shaw in Learn C The Hard Way. For some reason, the most brilliant devs I’ve worked with all used Vim, so I can echo this statement.


👤 n0n0n4t0r
When I started like 20ish years ago, you didn't have all that fancy IDE stuff thrown easy at you. For a matter of fact, I didn't even have access to a stable internet. So I learned a lot and relied on my memory.

It had many drawback, it had some upsides like really having everything stuffed in my head and learning probably more promptly by searching/memorizing.


👤 oleg_antonyan
In dynamic languages things like autocomplete often make it worse, they cannot identify the correct types and locations 100% of the times. So at some point I decided to avoid these and got used to it. To the point where I avoid QtCreator for Qt/C++ projects b/c autocomplete and fancy navigation features become annoying and distracting

👤 ern0
1. A friend of mine told me that he was writing a program, then he needed a function, which he just wrote. At compilation, turned out that the same funcion already exists with the same name. He created it a hour before.

2. I remember all my variable names. In a module. For a while.


👤 mithametacs
I had no choice most of my career doing Rails.

Now I do C++ and I would fight to the death to keep autocomplete.

But Copilot I bought a license for a got a refund for after a few months. In the net, it wastes your time.

And I mean, copilot in particular is especially bad. It refuses lots of valid programming questions. Other LLMs are better. But they still are wrong a lot.


👤 xenophonf
Autocomplete:

It's nice, but using non-shitty libraries with good documentation is nicer.

Language servers:

Bloat.

Copilot:

Why bother with AI when I'm good at writing buggy code myself?

Remembering types and fields:

Don't trust memory. Write documentation—if only for yourself if not for your colleagues.

The language server go-to-definition feature:

That doesn't require a language server, just a cross-reference; see also ctags, bloat (above).


👤 jmclnx
You just type or copy/paste, but the main language I use, most statements are terse. But I have personal templates for a few languages. As you go on, most of the programs are pretty much close to what you have already done.

Like the old saying, there is only 1 COBOL Program, all others were copied/pasted from the original.


👤 zahlman
> Do you just remember every type and field in a codebase?

I remember the functions that are relevant in the current context, yeah. I don't design things that have a lot of properties in the first place; and I'm concerned with what objects can do, not with their types (and I use Python, which empowers me to write this way).

> What does your flow look like?

Generally I keep a terminal open as I write in an editor window; most of the time it's cd'd to the project root. (Hmm, maybe I should be using `pushd` and `popd` more....)

At about 200 lines of code in a file or 10 lines in a function, I start looking for ways to split it up or organize things better. At double those values I start panicking about it.

Every identifier name is an opportunity to explain something crucial about the process.

I rarely use inheritance any more, let alone multiple inheritance. Jack Diederich's "Stop Writing Classes" (https://www.youtube.com/watch?v=o9pEzgHorH0 - a clickbait name, but you know how it goes) is part of my mantra; `functools.partial` is very often a better tool for the job.

> What do you do if you need to look up the definition/implementation of some function which is in some other file?

I can tell where it is because the import statement tells me the package name, and I have a single file hierarchy for code in my project. But most of the time I can just trust myself that it works the way I expect it to, because I wrote it, and I followed conventions when I wrote it, and I made sure it fundamentally doesn't do very much or have a complex signature. (If it operates on complex data, I build that up - step by step - rather than passing all the pieces as separate arguments.)

If it's someone else's code, generally I'm going to look up the documentation anyway, not the code. If for some reason I have to figure out where the code is, I can do it easily enough, because I know where third-party libraries are relative to `sys.executable`, and I know where that is because I use venvs in a standard and predictable way. (Oh, but I could probably improve this with a one-liner Bash function, brb....)

But I do also have the option of checking things at the REPL. Python does a lot to help programmers feel like they don't need an IDE. (Avoiding boilerplate is also huge here.)


👤 mmphosis
Delete these five words.

Imagination, not pagination. Destroy all software. Don't let some tool make you a fool because the safety is off and the training wheels are no longer there. Turn off the defaults, the noise of misinformed conversation, non-existant completion of words lost in translation.


👤 alfiedotwtf
I have a friend who still to the day doesn’t use syntax highlighting. People like living on hard mode lol

👤 agumonkey
I mostly need LSP on system with tons of ad-hoc definitions. react/typescript is one example, there's so much type definitions that browsing would take eternity. for non framework python codebase, the shell completion will be enough most of the time

👤 ww520
I use partial autocomplete. Emacs has the universal autocomplete that's not language specific but gets it right often. I do use LSP on languages that have support. For languages that don't have good LSP support, just search. Emacs has great project wide search.

👤 sebi42
Even tough I use copilot on a daily basis, I don't really miss or notice it's miss in environments where this isn't possible. I guess it hasn't replaced my skills built over the past 20 years.

👤 moody__
I write a lot of code for 9front within 9front, all of which is done through the sam editor. While sam does have a powerful general purpose editing language, it doesn't do syntax highlighting or any sort of language aware tooling (LSPs, jump to def, autocomplete, whatever). However I didn't start off with this, I'm not too old (in the second half of my 20s now) so I did take the tour through Java IDE's, tricked out vim configs and vs code as I was learning how to program. However when I moved to working on 9front I actually felt like the lack of these features made it easier for me to focus.

I like to think of code as not that much different than prose, they are both strings of text for communicating information, typically in a fashion of one thing after the other. I think most people would find syntax highlighting for prose to be more annoying than not (outside of perhaps seeing grammar rules for learning). Once I tried reading and writing code without syntax highlighting I found that it encouraged me to actually read and digest code instead of just skimming it. Compare it to reading prose with and without certain subsections highlighted.

Autocomplete strikes me as optimizing the wrong end of the problem. When I'm writing code I generally am spending a lot more time thinking about the problem space or considering possible implementations then I am having my fingers on the keyboard actively typing it out. In general I think the more you're able to think carefully about code in general the smaller it gets, so I find it hard to believe that by making it easier to quickly dump large amounts of text on the screen you're really gaining much. I think there should be a larger focus on reading and understanding code than writing it.

Stuff like code search is quite nice, and even in 9front we do have some scripts and tooling built-in to help us do that. We have programs like 'Bfn' which can search for a function and send it to your text editor, file names with line numbers can also be quickly sent to the editor as well. I think advancements in tooling that helps people move around in code are generally great, the time spent searching for something is generally not something I enjoy. This was perhaps the nicest part of LSPs in my experience. However I do also think that if you make it quite easy to jump around to lots of different files there is less of an incentive to carefully consider how you're laying out your code. How 9front works where there is some tooling to reduce the monotony but not enough to make it easy to traverse a couple million line java project strikes a nice balance for me.


👤 redman25
Before switching to neovim, I used a split terminal with vim in one split and the other split for running `rg`, `make`, tests, etc. It's amazing what you can achieve with grep especially if you use something like ctrl+p in vim which can use ripgrep for fuzzy finding.

👤 kazinator
> One example is that I cannot live without the language server go-to-definition feature. What do you do if you need to look up the definition/implementation of some function which is in some other file?

Whatever you used for that before LSP.

Oh right ...


👤 egorfine
I either use Vim in the terminal or VS Code. When I'm in the zone, I'm perfectly fine using either tool and don't think much of it.

But I tend to use vim more often when programming C or bash and way less when I'm in JS context.


👤 MomsAVoxell
Terminal, grep, silversearcher-ag, cscope, tree, doxygen, all in union with iTerm geometry hotkeys well-tuned, Hammerspoon for window management, and copious amounts of real-estate for doc-reading, which is 60% of the effort.

👤 botten
My basic setup was vim/emacs (only as text editors) + grep/sed. It is totally doable and it is possible to be really productive but makes no sense when you have actually tried out adding some integrated tooling to your editor.

👤 guerrilla
Yes, you just know what you're doing. The more you do it, the more better you know it.

👤 bobmcnamara
> What do you do if you need to look up the definition/implementation of some function which is in some other file?

I name my code in a pattern that makes sense to me about where a function should be implemented.


👤 replyifuagree
>What do you do if you need to look up the definition/implementation of some function which is in some other file?

I work on a massive monorepo that the LSP chokes on regularly.

In the end, global search is my sweetest friend


👤 unconed
How? I remember where all the code is. And I watch juniors flail without a picture of the codebase in their head, because their IDE incorrectly taught them it's not their job to know.

👤 zulban
I have a hobby project that turned into a fairly successful commercial project. I hardly use any IDE features. Sometimes, I write a new utility function like "get_abc_from_xyz_index" only to discover I already wrote it a year ago in the file I chose to put it in. So not only is the project well organized, but it's all me so I'm very familiar with it. Lots of tests. I also type extremely fast so unless autocomplete is perfectly tuned, it can just be annoying handling various languages and maybe on different machines. HTML tag closing is a good example of an annoyance.

Since I've been doing this for years, it bleeds into my work too, where compared to my peers I tend to use fewer dependencies and IDE features.


👤 pjmlp
They program as I used to in the 1980's and 1990's until Borland and Microsoft introduced code completion to the masses.

Typing the whole thing, while having manuals open for quick cross-checking.

Using text search tools to find code.


👤 shahzaibmushtaq
IDE features are meant to prevent mistakes, errors and done tasks quickly. Do not to use it as a guiding map all the time to find your lost treasure i.e. code part you wrote a few hours or a while ago.

👤 cullumsmith
vim with zenburn theme. grep/find when I need to look for something.

I've been programming professionally for about a decade, and the basic Unix tools have always "just worked." They're available everywhere, my dotfiles are easily portable, and there's no licensing or procurement to worry about with corporate beancounters.

I'm sure I'm giving up some marginal level of efficiency, but I've watched so many fads come and go that I'm OK with the tradeoffs of "old reliable."


👤 SAI_Peregrinus
I prefer autosuggest to autocomplete. And I didn't like copilot, doesn't seem to work very well for embedded code, though it's been a while since I've tried it. LSPs are useful.

👤 johnchristopher
I do wordpress dev at the moment and there are some blade template and I don't know how use autocomplete/LSP to hunt down functions/methods used in blade templates.

Makes me sad :(.

At least xdebug works.


👤 deniska
At some point, python became the language I use the most. And its IDEs… are frankly not really great. They are doing their best, but given the dynamic nature of the language, the experience of using autocomplete and other similar features is often jarring enough, when it doesn't do what you want it to do, to be annoying.

So I mostly stuck with really simple text editors (first likes of notepad++, geany and gedit, later switched to barely customized vim). You learn the language, you learn its standard lib, you learn the libraries you use often, you learn to navigate their docs. You learn the project you are working on, and remember how things are named. I do use a simple autocomplete (ctrl+n in vim), but it's more of a typo preventer (or a typo propagator, depending on how you look at it). It autocompletes every word in open files. Which might be more handy than it sounds, because it will autocomplete stuff not typically being autocompleted in IDEs, like json keys, or file names in the open directory listings, or even outputs in the open terminal session.

As for navigating unfamiliar code bases and "go-to-definition": it's grep. Just search for a substring in the whole project. You will find the definition. You will also find some other interesting stuff, which "normal" IDE tools wouldn't look into. Heck, you'll find interesting comments, interesting name clashes, interesting usecases for a thing you were looking for. And it's a language agnostic skill. You don't need another bespoke IDE, you don't need to configure some weird LSP to navigate unfamiliar code base even in not so familiar language.


👤 newusertoday
i do search with rg its good enough most of the time, i rarely need to use lsp. I also do it in emacs which kind of abstracts these things away from me it almost looks like lsp. I do use autocomplete but its on opened files/buffers its not projectwide works fine. I don't use co-pilot but heavily use ai so most of my programming these days is editing instruction to ai. Fix this ui, create this method, make it modular, give me skeleton flow, lets debug this, etc.

👤 resters
You just skim over the API docs and learn the APIs. Grep can help look things up. Depends a lot on how many new APIs one is using and how non-trivial their implementations are.

👤 jve
Wow, surprised I look like living in a different world, enjoying when documentation pops up as I type. So surprised that many people don"t like Intellisense stuff.

👤 thuanao
I don’t use autocomplete for the same reason I use a single monitor: Distraction.

And I’ve noticed my co-workers who use IDEs and multiple monitors are no more productive.


👤 justchad
I use an app called Dash from Kapelli to access documentation for classes and methods. It’s a game changer, even if using a LSP. I do use copilot though.

👤 oytis
Pretty impossible for anything JVM-based IMO. But I am mostly working with C++, C and Python, and it's all doable with grep, vim and a tiling WM

👤 bregma
I'm old. I use vim with no plugins, no LSP, no autocomplete. I use the command line for everything but editing. Works just fine.

Now get off my lawn.


👤 ilrwbwrkhv
Yes, I code in Rust and I don't use a LSP or Rust analyzer.

I write code. I mostly remember things but I check the documentation often.

Docs.rs is always open.

Then I compile it and fix the compiler errors. The Rust compiler errors are very nice and friendly. So it's not that difficult.

I mean that's how C and C++ programmers worked for many many years.


👤 thex10
I refer to the documentation like my forefathers did. But I do happen to work with a language with good documentation (Elixir).

👤 mamcx
I have done +12 langs (used for work) with a variation of some using an IDE, a user-facing GUI (like Excel/VBA/SQL Admins), others just a text editor, etc

Some have auto-complete, others do not.

I use some of these combos at the same time.

The main thing I learned is that certain languages are made for one way or another.

For example, python, SQL.

There is not much you get from a IDE for python, and a good editor make wonders. SQL is braindead and bad designed, so the only moment you wanna to autocomplete (for get fields) any tool I have used fails (ironically, this one thing where copilot actually improves it).

So, if the language is made to work well without ide, it will work well.

What is a terrible mistake is refusing to use an IDE (or IDE-like capabilities) for languages like Rust, C++, C, etc...


👤 deadbabe
The only tool you need really is a very powerful search that lets you jump around with only a few keywords.

👤 Alifatisk
Because I don't have any other options, the DX has been like that when writing in Ruby.

👤 RoxaneFischer1
for me "artisan" devs see coding as a craft, avoiding modern tools to "stay sharp" or stay closer to the metal. its cool admirable but really not adapted for complex modern systems. Tools exist for a reason—maximizing productivity and reducing cognitive load.

👤 mattlondon
Code should be intuitive - i.e. it should be implicitly obvious about types and so on.

Perhaps if you are working on things in a very "scatter gun" way - i.e. you write a function here a function there but never really go deep in a codebase to really grok it then you'll never really get an understanding of it.

In the old days - or when LSP just doesn't work which for me is probably more than 50% of the time it seems - I rely/relied on compiler errors and/or test failures to detect problems. You can just open up the file that contains the function you are calling etc to go read what it expects.

FWIW I use all the fancy bells and whistles in terms of autocomplete and LSPs when I can (and when it works it is a great help) but I never use AI directly in the code-writing-flow. For me this is akin to the bad old days of junior/offshore Devs just copy-pasting code they found online/on stackoverflow and trying to write glue code to connect it all up. You end up with a real mishmash of inconsistent approaches/styles, duplicated code that does the same thing but in different ways, code that kinda-but-not-quite does what it needs etc, usually no coherent tests, etc etc - tl;dr super low quality and hard to maintain mess.

I will certainly use AI to help me with a few things, perhaps provide an example way of doing something/inspiration, but it is more akin to rubber-ducking and the output of an AI is never directly used. I view it as a quicker way of going to look up the right algorithm in a text book or something.


👤 mrkeen
I keep a few windows open, e.g. the module I'm editing, and whatever module I also want to be reading. If it's not my code, I just have the doc open [https://hackage.haskell.org/package/vector-0.13.2.0/docs/Dat...]

I use ag (silver searcher) to instantly match any usage across the project - frontend, backed, SQL strings, whatever! Also since it's CLI, I can pipe/grep to refine the results even better.

Or alternatively I just make the change I want, hit compile, and get a nice list of all the breakages.

The language is way more important to me than the "tooling". Especially when certain features can oppose each other:

Example 1: null detection. Your IDE prides itself on finding nulls, when really your language designer was the one that put them there. Most langs don't allow reading uninitialised data, so if you accidentally read a null, it's because someone deliberately wrote a null. Far easier to not have nulls, than to insert them and take them out later.

Example 2: IDE type-overlays. If I write 'User user', my IDE scolds me and tells me to write 'var user' instead. Then the IDE has the audacity to insert a small grey 'User' back into my text because it knows 'var' isn't helpful.


👤 VMtest
my comment on greppability from 3 months ago could be relevant https://news.ycombinator.com/item?id=41467681

👤 NikkiA
I use my squishy pinkish-brown thing to create a malleable model of the program

👤 liveoneggs
who has all the time to set that crap up for it just break tomorrow?

How does anyone handle the visual distraction/interruption of those g-d popups?

If I could get syntax hints and docs in a fixed space I would probably do it


👤 whoknowsidont
Honestly, it's really not that difficult if you give it a try. I grew up in a era where autocomplete was complete garbage and sometimes it would even cause issues (slowness, crashes) in the IDE.

Give it a few weeks (or even a few months, I don't know). You quickly learn the "rhythm" of codebases -- and then eventually you've seen it all to the finest details.

Then it's "ezmode." And it's not just for one codebase, you become better and better at realizing the way a code base is architected (code base being anything from an actual application, to an SDK, etc).


👤 ruuda
Ctrl+N in Vim, and API docs.

👤 b65sol
Honestly, I've just been too lazy to set up anything beyond the basics. It's that whole "I'll learn a new tool when I have a concrete reason to do so" type of thing. (Admittedly, it's one of my bad habits.) So when I need a non-runtime definition (I have autocomplete for runtime), I just search for it. Or look it up in the auto-documentation. Likewise, for libraries I keep most relevant documentation on hand.

👤 max6zx
Not sure about others who commented in this post, but all guys I met in real life who refuse to use advanced features of an IDE like autocomplete, refactoring ... are either: 1) have never work in a truly large scale projects (and usually familiar only with weak type languages - which IDE cannot help much so they cannot grow over a certain limit - chicken and egg?). 2) do not know what are the differences between a rename/search features offered by IDE and terminal commands to achieve similar objectives. 3) do not really care about productivity (use find & xargs for searching and does not even bother to write a script? meehh)

So when someone says he do not need an IDE because its feature are just distraction, my first question is always about the biggest project that he has worked with, and the second one is how he do rename/navigation/... with his code base. Never find a single guy does not fall out of these 3 groups.

Copilot is another thing for me. The reason is its accuracy is not good enough yet. The moment it can produce code align with my intention 100% accuracy, just like how search/refactor/suggestion that IDEs are currently offer, I will include it in my workflow instantly.


👤 ChrisMarshallNY
In the case of Xcode, I use it, but carefully.

The new "intelligent" autocomplete is annoying AF.

In some cases, it's great. Gives me a suggested function call that exactly meets my needs.

In other cases, not so much.

Here's a [hypothetical, but not really] example:

Say that I declare a property, like so:

    var userWantsMeToCreateWidgets = false
Then, later on, I want to reference that property in a function:

    func seeIfUserWantsWidgets() {
        if userWantsMeToCreateWidgets {
            .
            .
            .
        }
    }
When I start writing the if line, autocomplete invariably suggests something like:

    func seeIfUserWantsWidgets() {
        if *userDoesntWantWidgets* {
            
Where the heck did that come from?

But wait! That's not all!

If I later reference the function call, autocomplete often does this:

    seeIfUserWantsWidgets(*to: .paint*)
WTF???

It will often hallucinate variants of API calls, as well. I have to be careful, when adding delegate functions, because they are completely legit, as far as the compiler and linker go, but will never be called, because their signature is wrong.


👤 AndrewKemendo
Switching/Learning costs are higher than my expected benefits

👤 syngrog66
To folks over a certain age this question is hilarious. ;-)

👤 kaamkiya
I never really thought about it. I guess some people just like having those features, but I find them annoying.

I use Neovim with 0 plugins (apart from themes). I code in Go, and frequently reference https://pkg.go.dev.

When I do need to code in VS Code (rarely), I find that the autocomplete just gets in the way of my though process. It's like having a train of though barreling along and then suddenly an elephant gets on.

Also, I didn't even know what an language server was until looking it up after reading this post.

About Copilot: I have many problems with AI. They guzzle electricity, tend to be run by corrupt corporations, and are filling the internet with BS.

If I need to look up the definition/implementation? `:vsplit` works fine. If it's on the internet? https://pkg.go.dev.

If you don't trust me, you can check my dotfiles: https://codeberg.org/Kaamkiya/dotfiles


👤 leed25d
Emacs, etags, elpy.

👤 kerkeslager
I use vim on the command line, and screen to switch between terminal and vim. vim does have autocomplete, but it doesn't pull names from the entire codebase, just from the current files open.

I don't remember every type and field in the codebase--I have to familiarize myself with them when I work with them, just like you do--and if you don't familiarize yourself with your types, the IDE telling you what your type is, isn't going to be particularly elucidating. With good code, it's usually pretty clear what the type of a variable or field is, even if the type definition isn't in your current viewport. If that's not the case, your code is likely overcomplicated, and needs a refactor. If there's too much inherent complexity in the problem to allow for that, then you've no choice but to keep a whiteboard handy to sketch stuff out--that's much easier and more useful than anything an IDE does to trace complexity.

Go-to-definition lets you lose track of the big picture, because you don't have to have a working knowledge of your project's file structure to work around it. The result is often multiple definitions of the same thing with loose translation layers between them which people don't really touch often enough to feel obvious pain from, so they end up just sitting there hurting performance and introducing subtle bugs whenever adjacent code changes. I've worked on a few Java/C# codebases like this.

It's really important to me to read and understand all the code around what I'm modifying before I make a modification, so I can make exactly the change I want to make and nothing more.

Workflow: Make sure you are on the same page as product with what the feature is, asking any questions you can think of. Write an integration test, if possible (it isn't always). If not, write a test case for manual testing (it's better if you can get the testers to do this, and even better if you can do it with them). Get an architecture in my head, or draw one on a whiteboard if it doesn't fit in my head. Visualise the "flow" of data through the different units, and what needs to change--if the feature is complicated, write this down so you don't have to start from scratch figuring it out tomorrow. Start at the beginning of that flow and write a unit test, then implement it, cycling through unit test and implementation in a circle until each unit change is implemented. Then run the integration test and manual test. Take a step back and see if there's anything you missed. Deliver it to product/testing.


👤 ncr100
Just remember it, love the language.

👤 knorker
I've set up LSP a couple of times, but not been wowed yet. Didn't feel like it added much value. It's on my TODO to do in again, though.

For your question about go to definition: not like it takes much time to open a file and search. Yes, of course objectively it takes longer, but I don't feel like my coding speed is limited by my typing speed. (a mouse is not involved when opening a new file)

I mean to set up LSP again because it has to be better. But in the past, when it's broken or I code on a different machine I've found that I don't miss it, or even necessarily notice it being gone.


👤 GnarfGnarf
LSP = Language Server Protocol

👤 twism
Alt + Backslash , YAS, etc. Emacs

👤 jlnthws
Rigrep and fzf in bash and vim.

👤 jade-abc
Hi, younger programmer here who's first programming experience was Visual Studio and .NET (that's a lie my first programming experience was a decade earlier with yabasic and notepad but given that I only ran about three programs I'm loathe to count it) my tiny laptop struggled to run Visual Studio and I was working a lot in server admin so naturally started using vi. Vi came without any modern features and when I tried to move back to Vs code I hated it so much. The screen was so busy and every time I typed something I was distracted by 100 different suggestions, sometimes I would accidentally press a key and paste a load of code in I didn't need. By this time I had already gotten proficient at vi keybindings, got any information about an API I needed from scouring the documentation/manpages(please every one make a lot more manpages). I then decided to see how much I could strip back without really affecting productivity. Anyway a few months ago I switched off syntax highlighting and now other people's editors look like a mess to me. Anyway I love that I can program in any environment on any machine as long as a text editor is available. Makes me feel like I'm not beholden to Microsoft or jetbrains when they inevitably tighten the licenses and I think it makes me a better programmer because I have to read and think about the APIs I'm calling.

tl;dr modern ide's abstract you away from compilation pipelines and make you more reliant on intellisense than reading docs. Syntax highlighting is a psyop designed to kill the art.


👤 loeg
Yeah. I don't use autocomplete, LSPs, or copilot. You just remember as best you can, choose better variable/type names that aren't a full sentence, etc. Most of my time isn't spent typing.

I do use and really like go-to-definition, though. LSP is one way of doing that (probably the right way) but historically we used tools like "ctags" for this (and I still do, just because I've already got that workflow set up).


👤 rebeccaskinner
These days I mostly write Haskell, so I'll focus on that. When I'm writing Python, Rust, or C the stories are similar broadly, although may vary a bit in the specifics.

I don't think the way I work is all that different from the way people who use a lot of IDE-like features work. The main difference is that I prefer a pull-based approach to getting information, rather than having my editor push information at me or try to do things for me.

My typical setup for a project is to have my editor (emacs) open with code, and separately to have my project open in a REPL (ghci). For smaller projects I use haskell-mode, which lets me open a REPL with the file I'm working on loaded automatically. At work our codebase is a bit too big and our build system a bit too complicated for haskell-mode to be able to manage my repl, so I use a separate tmux buffer to open ghci.

I can do a lot from my repl. If I want to know the type of something, I can either look it up using the repl if it's a top-level binding, or I can add a type hole and reload the file if it's something that's not directly available in my repl. I can also see what instances are defined for a type, what functions are available in those instances, and where the type is defined.

In addition to my repl, I'll usually have a shell open in my project. If I'm trying to figure out where something is defined, I can just run a command to query hiedb, although in reality it's often fast enough to just use ripgrep.

If I'm trying to remember the name of a file or where it lives, I will typically use fzf, either in my shell or in emacs. I can usually remember enough about the name to at least narrow it down to a couple of options.

For things that live outside of my project, I wrote rofi-hoogle (https://github.com/rebeccaskinner/rofi-hoogle/) to let me search packages and documentation from my desktop with a simple keyboard shortcut. It also lets me jump to the online documentation if I need to read more than the type.

I don't use copiolot or any other sort of AI auto-complete at all. Occasionally I'll present a simplified version of a problem to ChatGPT and ask it to write code, or I'll ask it to review some code, but I typically do that through the web UI. I keep intending to get it set up in emacs but I haven't bothered yet.

I wouldn't necessarily say that other people should adopt my way of working, but it's the best way of working that I've found for me and my own quirks. I've tried IDEs every so often, but I find that the constant distractions make it hard for me to focus on the task at hand- whether it's things popping up in my field of view, auto-complete moving my cursor around, or error messages popping up because I haven't finished the code I'm writing. I'm probably slower at the IDE-specific tasks than people who are really good with IDEs, and maybe even slower at those specific tasks than I would be using an IDE, but the benefit of being able to eliminate distractions and focus on the code I want to write outweighs the cost for me.


👤 fsmv
I read the documentation

👤 beej71
I admit this is my personal shortcoming, but when the IDE pops up anything while I'm typing I find it very distracting and damaging to my flow. It feels like someone interrupting me every spoken syllable. And they commonly cover up other code.

I want help when I explicitly ask for it.

Younger devs might not have this issue.


👤 bdhcuidbebe
Ripgrep ;)

👤 forgetfreeman
Eh, it comes down to a combination of putting time and effort into mastering the tools of your craft and having docs open on a 2nd monitor as needed. Put in enough reps and you just organically memorize huge chunks of language/framework details. As for finding function declarations on the fly, have grep will travel.

👤 mixmastamyk
Editors have had go-to-definition a decade or two before lsp.

I usually use Python in medium-size projects and remember the types for a couple of files at least. It’s almost always one of the top five builtins or a custom class I wrote or modified. If in doubt I click on the word and it highlights everywhere. Usually obvious what it is by context.


👤 redcat77777
oh, somebody is hunting for content?

👤 dlenski
> and recently copilot

I, for one, have never even used ChatGPT. ¯ \ _ ( ツ ) _ / ¯

I'm a software engineer, pretty highly regarded as very skilled by everyone around me, almost entirely self-taught (programming since age 7), and have worked at 2 household-name companies (and now a spin-off of a third). The only computer science class I've ever taken was a PhD-level introduction to machine learning, in the mid ’90.

I've never seen any task _where the details matter_ that AI appeared to be any good at. For example, I've seen a coworker trying to demo for me how quickly an AI coding assistant could fix a bug in a parser's state machine… but the AI made a mistake, which I spotted immediately.


👤 vouaobrasil
I learned to code when the only thing available was syntax highlighting. I mean come on, if people with punch cards could do it, a nice editor with syntax highlighting should be enough!

👤 Klonoar
I somehow just have a significantly large working memory in my head for what I'm trying to do, and then I'll look up a method if I really need it.

Grep, etc to find shit.

Then I dunno, it just kind of works.


👤 bitwize
Thank you for this post. By making it, you have attracted other people from Hackernews who've learned to "switch off the targeting computer". It helps to feel not alone.

So to answer your question, hmm.

I started programming -- well, I started programming the way many xennials did, in BASIC on an 8-bit micro. But when it came time to use "real" programming languages and environments -- your C++, your Pascal, etc. -- it was typically on DOS/Windows machines with an IDE. I became a Linux convert in 1995-1996 or so; I kept Windows around but just found myself wanting to use it less and less. So I had to think of Linux -- and, if possible, free software -- replacements for all of my favorite Windows programs including Borland C++ and Microsoft Visual C++, both of which were at the time roughly coequal tools for serious development on Windows. (It would take a few years for Microsoft to consolidate its developer tools into Visual Studio and then eat everybody's lunch with that.) So you know, Microsoft Paint had xpaint, and Photoshop had GIMP (still at version 0.54; you think it's rough now?!?) and Visual C++ had....?

The guy who introduced me to Linux in college was an Emacs advocate as well, and I'd heard of Emacs probably through Micro Emacs on the Amiga. So I decided to try Emacs (it had to be better than nano or vi[0]!) and learn how to use the command-line compilers and Makefiles as well, and these tools cobbled together would be the rough equivalent of Visual C++ with all its features. Note well that there was much less difference between a commercially available IDE and a text editor with a compiler bolted on in those days than there is today -- Visual C++ wouldn't get IntelliSense until 1997 or so[1].

So right from the jump -- before even trying Linux or Emacs or anything -- I learned how to wield APIs by studying the docs and remembering the names of things. Class, method, and function names to me were just like any other vocabulary. Just as you might learn the name of a new bird -- say the Spencer's Warbler -- but not just the name, the association between the name and what the bird does. So it goes with APIs. You learn that there's a function called CreateCompatibleDC, that it takes an HDC param, and what it gives you in return. If you're vague on any of the details (param type and order, return type, details of behavior) the docs are always a keystroke or click away. This was true even in Emacs which gave you a choice of two man page viewers, or you go to the web and look it up. Simple as.

Since learning to work well in Emacs, I have revisited IDEs from time to time and found them to be distracting. They don't have the features that I need. Even if they be extensible they make extending it to add those features difficult. And they give me a lot of features I didn't ask for or want. It seems like the IDEs are designed for corporate drones, to optimize standard applications being developed in standard ways. Even in the times I've been a corporate drone, never once has plugging forward in a standard workflow suited my needs[2]. I have always needed to write a bit of Emacs Lisp to help smooth out the kinks in my workflow -- running certain database queries, for instance, or monitoring and managing Docker containers for the app I'm working on -- and give access to all the weird little things I have to do on the daily to myself at a keystroke. Doing my coding in an IDE, for all the convenience afforded by some of their features, is full of friction, and I never reach that smooth fast state of flow the way I can in Emacs. I'm sure I could get faster by practicing in the IDE, but I'm always unsure if I would gain enough in productivity to justify the time investment in learning to do so. (Visual Studio Code, I know, is absolutely "not better enough" than Emacs to justify completely overhauling my workflow for it. There's still some doubt about IntelliJ for me in that regard.)

Go-to-definition is one of the few actual productivity enhancers modern IDEs give you, just from a standpoint of being able to walk a code base to find out what everything does as you study it. For most programming languages, it could be simulated with ctags/etags in vim or emacs since forever ago.

[0] Hail to my vi/vim brethren; vi was actually my first Unix editor and I still use it to this day. I found its modeful operation inconvenient in 1995, but today I don't see vi and Emacs as rivals, just two different approaches to achieving the same thing which is providing a flexible, real-time hackable development environment in contrast to the IDE/Visual Studio Code school which optimizes for standardized workflows and is absolute friction town for everything else.

[1] If you are unfamiliar with mid-90s software development, I recommend you go onto Internet Archive and look for old versions of Borland or Microsoft development tools, and install those in like a VM running Windows 95, 98, or 2000 just to get a feel for what they were like to use back then. They feel very bare bones compared to what we use today, yet large companies ran on client-server applications written in them.

[2] I've noticed this even in the Visual C++ days; Microsoft really wanted me to use the MFC library, and what I was writing at the time (a game for Windows 3.x) had absolutely no use for the "document/view model" or anything of that sort. The engine also didn't mesh well with how MFC handled events; and at the end of the day, the difference between event handling code done the MFC way ("message maps") and event handling code done the regular way (writing and registering a WndProc procedure for your window class) was really about the same, so MFC didn't really save me much. But if you committed to MFC, you could mash a button and skeleton out an app in an instant, and then it was just a matter of filling in the blanks. I felt I learned more, and could gain a bit of code efficiency, by writing everything myself.


👤 mekoka
I'm a long time i3, tmux, vim/nvim user. You can see a pattern. When I write code, I typically have a bunch of i3 and/or tmux windows open with dedicated tools ready to execute the necessary commands. Linters, compilers, containers, http clients, db clients, REPLs, log viewers, doc viewers, notes, tests, etc. All nicely organized and readily accessible a few finger taps away.

For the longest time I've only used a dumb variant of autocomplete that is scoped to only suggest names found in files that were loaded in the current editor session. It's not context aware like an LSP would be. It may sound bizarre, but I never really felt that I missed much. C-P/C-N, scroll one or two items away and most times I get what I want. If I needed to use an unfamiliar feature, I'd open my past notes or the docs and skim through them, or I'd reach for the REPL. But working like this, I think you also develop some extra awareness and other tacit optimizations that reduce the need to do this sort of things often. You remember many small details, you develop a knack for taking notes, you get efficient at using external tools, you learn to quickly access docs from REPLs, that sort of things. Someone else mentioned code organization in a comment. That's definitely a big deal.

I've often been fascinated by the approach of transforming the editor to integrate all the things for which I have separate tools. So I decided to try it out for a few months (Neovim has some powerful plugins). I ended up keeping some of the suggestions, mostly the ones that aid in navigating the file system within the editor and finding files (e.g. Telescope). But I think my LSP experience has been one of the most distracting programming experience I've ever had. Perhaps if I'd given it more time, I might have gotten use to it. But it felt less productive for really marginal gains.

I think describing my experience can bring to light that some of us prefer working depth-first, while others are comfortable breadth-first.

The "real-time" nature of the warnings and suggestions was inappropriate for me. It felt like trying to write an essay and being told to worry about form and grammar, while I'm still developing my thoughts. Laying down the foundations of what I'm trying to express and meanwhile things popping up in my face completely out of context. By context here I mean at the wrong time. I'm currently laying down the structure of my thoughts and I see the editor issuing warnings about syntax or wrong imports. Please, this is not the time. Let me think. Stop distracting me. I'm ok to not have it right on the first try. When I run the damn thing, you can complain all you want. Don't worry, I'll understand what you want and will fix it. Right now I need to think. This is not grammar time.

The fix for the above was to configure the LSP to be mostly silent and on-demand. But then there wasn't much difference to using it externally to the editor.


👤 greentxt
Grep?

👤 bhaney
I primarily use a pretty minimal vim setup, and I use it a lot differently than most devs these days use their editors. I don't really have a "home" machine for programming, I just ssh into whatever box the code is going to be running on and use that machine's vim. I rsync over my vim config/plugins if I'm going to write more than a few hundred lines from that box, or if I'm using a language that doesn't have good native syntax highlighting and needs a plugin. For work at least I use local vim on my work-provided laptop, but other than that I don't really have a tight association to any particular dev environment. If it runs vim I'm happy, so I can pick up and start writing code comfortably from anywhere.

> how do you do it? Do you just remember every type and field in a codebase? What does your flow look like?

It's very different for a codebase I'm familiar with vs one I'm still learning. I do the vast majority of my programming on the former, where I don't feel most of the features you mentioned really matter. Yeah, I remember the types and fields. Usually they're already being used several times in the same file I'm already working in, so it's rare that I even have to make an attempt to recall something, and even rarer that I fail to. When I need to change or add something, I simply open the relevant files and write the relevant code, because I know where it should go.

When I'm learning a codebase, there's a lot of jumping around and looking things up to get familiar with it. I've found that using IDE features during this stage makes me slightly more productive in the short term, but makes me much slower at becoming familiar with the codebase in its entirety (or the subsystems relevant to what I'm working on, in very large codebases). Being familiar with the codebase in its entirety is very important to me and I feel like it enables me to design features and bug fixes much more reliably. My number one priority when working on a new long term codebase is to get to the point where I can fit basically the whole codebase in my head (with a fidelity depending mostly on the size of the codebase), and I do that much better when I'm working on it raw and not outsourcing my understanding to tools. Then once I have that complete understanding, I no longer need the tools anyway.

> What do you do if you need to look up the definition/implementation of some function which is in some other file?

I open the file it's in and read the code. If I don't know where it is (which is rare, especially because most languages and codebases have rules or conventions for file/module/function names), then I grep the codebase for its definition before opening the file. But usually if I'm in the Foo subsystem and need to check the definition for its Bar.baz function, I know it'll be in src/foo/bar.ext and I can "/def baz" or whatever to jump to the definition as soon as I open the file. I've been meaning to try getting used to fzf vim plugins for the last 5 years or so but I really just don't care enough to put in the effort. It's obviously slower to grep and open and search for the def, but the problem just doesn't come up often enough for there to be a good incentive for me.


👤 LeftHandPath
When I started writing code, I was using NotePad++ and tracking versions by... file name suffixes. And occasionally writing stuff on paper by hand, for the hell of it. It was awful. Discovering Git about a month into my programming career was, of course, a game changer.

The first IDE I used was Zend Studio [0], because I was writing a PHP application for the IBM i Series, and Zend pushed their IDE along with their licensed server [1]. (Note that in modern times, with IBM OSS for PASE, PHP for the IBM i can be sourced from e.g. Seiden Group for free). Zend Studio is eclipse based, and terrible - their modern landing page advertises PHP 7.1 support. About a month into using it (this would be sometime circa 2018), IIRC, the whole thing broke while I was tinkering with basic appearance preferences, and the application would no longer open. Instead of fixing it, I asked my manager if we could buy a PHPStorm license, since I kept seeing it mentioned in blogs and tutorials and it sounded nicer.

PHPStorm was an absolute game-changer. It was the first time I experienced the miracle of modern language servers. Go to definition? Holy shit! It can see errors before I test the code?! IT CAN HELP ME SPOT ERRORS IN MY JAVASCRIPT?

My PHPStorm license was probably the single highest ROI expense my company ever took on my behalf. That led to all sorts of rabbit-hole learning, like setting up gulp with babel and sass and autoprefixer back when we were supporting all the way back to IE10 on our websites.

When I went back to school for a BS CS, I downloaded CLion expecting as-good support for C++ (our curriculum's language) as PHPStorm had for PHP. I was a little disappointed, but from what I hear CLion is much better now (with the Nova engine). On another note, JetBrains threatened to suspend my account when they saw me using an educational CLion license on the same account as my corporate PHPStorm license... Explained my way out of it (as I was using the licenses correctly / following EULA) but it was a sour moment, especially considering they recommended people join all of their licenses (personal & professional) under one account [2].

Regarding CoPilot: I haven't used it and probably won't, unless they add truthiness to LLMs. I've found that actually typing my code is rarely the bottleneck, and sparing myself from typing is the "value add" most coding LLMs offer.

[0]: https://www.zend.com/products/zend-studio

[1]: https://www.zend.com/products/zend-server/ibmi

[2]: https://sales.jetbrains.com/hc/en-gb/articles/208460135-Can-...


👤 iamwpj
I've been through both aspects. I really wouldn't listen to any of the people in this thread. Advice in this arena is so specific to domain and environment. If you don't remember function parameters for every builtin or stdlib of your language(s), you should look it up in the docs or use the LSP provided feedback. I have to reference my own libraries for docs sometimes. I just find myself in too many different codebases in a week to remember everything.

I learned more Bash and Python from running Shellcheck and Ruff respectively. Frankly, if your code has squiggles that get on your nerves from the LSP/linter fix the settings ... or better yet, correct the syntax. gasp


👤 apex_sloth
One. Letter. At. A. Time.

👤 binary132
please tell me this is bait

👤 lloeki
> autocomplete

is rarely useful to me, I just type things out.

I'm just quicker this way. By that I mean that my stream of thought just flows, when thinking about autocompletion is like in another "brain space" which makes my mind stutter.

I don't know if I'm wall-clock quicker for real, especially as I'm not that fast a typer (certainly not as fast as I want to be) but the mental exercise is annoying enough that I prefer the smooth tarmac of typing it all vs the pebbled trail of jumping back and forth between thinking about the output of typing and autocompleting.

If some autocomplete produces a dropdown list the thing it does help me is a quick feedback as to whether I made a typo, but I basically never tab the autocompletion out.

Only time I do tab out autocompletions is on the shell, and mostly only for paths.

> language servers

I do kind of see the appeal e.g VScode's invoking this inline view of a method implementation right at the call site. In practice I never use it.

Another one is inlay hints in Vim, e.g with type information for dynamic languages (e.g Ruby when using RBS) or to correctly feed autocompletion.

What I don't like is how heavyweight LSPs "feel".

> and recently copilot

I tried Copilot a few times and it was a) slow and b) mediocre.

Slow is stupendously because it feels like I'm driving an autobahn, except littered with 10kph roadbumps.

Mediocre as it sometimes produces code that works, but most of the time is either wrong or flat out doesn't work; even for boilerplate its output is bad/inconsistent with the codebase/outright incorrect. So every time I have to enter a "review mode" state of mind and fix the damn thing, which ends up being slower than just fully typing the thing out in the first place.

> go-to-definition

:sp p lib/whatevs (backed by fzf) then /thething because codebases I work on are typically organised sensibly.

Or I just open a new tab and rg thething then vim thepath +:42

Unix as IDE is stupidly fast and powerfully flexible for me.

> Do you just remember every type and field in a codebase

Mostly, not everything but I do have a mental map to find things quickly with the above.

Rereading the above, I realise that maybe the takeaway is that I'm a "fixes radios by thinking" type of person, which means huge mental models and map of everything fit in my mind, then I reason it out and come up with a solution in my mind, and I just need to type it out as a final step in a sort of stream of thought way, so anything that gets between the mind and the characters appearing on screen is a major drag.

I don't think it is any worse or better than an IDE, it's just the way I work, and I've seen some people do crazy stuff crazy fast with IDEs/LSPs/LLMs just as well. It's just not my way of operation.


👤 nerder92
If your work is building Technology and you have a mental model such as: “it was better when it was worse”

You don’t understand the essence of your job.