Think of a set; let’s call it the grunt work set. Tasks that should never consume our cognitive bandwidth, deterministic and rule-bound chores: linters, formatters, dead code checkers, type checkers…

With generative AI, this set expanded and swallowed the code itself. The following tasks are now firmly inside that mechanical set:

  1. Boilerplate structures: Predictable skeletons that repeat across projects: CRUD layers, controller/service/repository scaffolds, DTOs, configuration classes, and API client boilerplate.

  2. Data transformations: Mapping one data structure to another: converting database models into API responses, parsing JSON and mapping fields, or filtering and reshaping arrays and dictionaries, chores that require zero creativity.

  3. Routine implementations: Code that involves no novel business logic or algorithmic design, merely chaining library API calls: making a standard HTTP request and checking the status code, or reading a file line by line.

  4. Test and verification code: Mechanical templates written to assert functions with already-known inputs and expected outputs: setting up mocks and fixtures, chaining assertion statements, or drafting one-off smoke test scripts and health-check calls.

  5. Infrastructure and deployment manifests: Declarative configurations bound by rigid syntax and specifications: writing Dockerfiles, defining Terraform blocks and Helm charts, composing GitHub Actions or GitLab CI workflow YAMLs, or writing Makefiles and deployment scripts, often copied from an older repository with only the variable names tweaked.

We used to handle these mechanical tasks with editor plugins. Then we automated them with pre-commit hooks and command-line scripts, going through our first tooling diet.

The second diet was around autocomplete. It started with simple word completion. Next came language-specific dictionaries, followed by LSP clients offering context-aware completions based on syntax and cursor position, and eventually evolved into model-backed completions with tools like TabNine. Then what happened? I stripped all of them out.

Now, I find myself thinking about how to simplify my editor even further: what else to delete, what else to remove. An editor must be fast, reliable, open huge files without breaking a sweat, avoid eye fatigue, and let me work uninterrupted for hours. My expectations from an editor are no longer centered on typing code, but on finding things quickly, inspecting diffs, running tests, deploying or releasing, querying databases, and managing Docker and Kubernetes services.

And most importantly, playing well with AI harness tools. I am still not sure how the future will settle here. Claude Desktop, Codex, and OpenCode now ship with their own editor capabilities, but each locks you into its own service ecosystem. To me, the editor still feels like something that should remain independent. When working with Codex or Claude Code, for example, I wish I could simply drive Emacs or Vim inside them. Alternatively, I look forward to harness tools being seamlessly integrated into PyCharm and VS Code. Yes, I know alternatives exist today; they are just not mature enough yet, so for now I prefer running them side by side.