← Blog
Narzędzia14 min czytania

Helix — edytor w Rust z wbudowanym LSP i tree-sitterem

Jeden plik binarny, który zna 342 języki, 303 gramatyki tree-sittera i 190 serwerów językowych — bez konfiguracji, bez menedżera wtyczek, bez wieczoru składania środowiska. Omawiamy model edycji odwrócony względem Vima, brak systemu wtyczek, którego dodanie od trzech lat wisi w recenzji, oraz lukę wydawniczą, o której warto wiedzieć przed wdrożeniem.

Edytor w terminalu przestał być kwestią gustu, a stał się narzędziem pracy w konkretnej sytuacji: jesteś zalogowany na serwerze klienta i musisz poprawić plik konfiguracyjny. Albo działasz w kontenerze, w którym nie ma niczego poza powłoką. Albo chcesz zajrzeć w kod bez uruchamiania środowiska zjadającego dwa gigabajty pamięci.

Klasyczna odpowiedź brzmi „Vim", a klasyczny problem z nią polega na tym, że Vim bez konfiguracji jest edytorem tekstu, a nie narzędziem do kodu. Podpowiedzi, przechodzenie do definicji i podświetlanie rozumiejące składnię wymagają zestawu wtyczek, menedżera wtyczek i wieczoru na złożenie tego w całość — a potem tej samej pracy na każdej nowej maszynie.

Helix (github.com/helix-editor/helix) odpowiada na to inaczej: jeden plik binarny, w którym wsparcie dla serwerów językowych i tree-sittera jest wbudowane. Nie ma czego składać, bo wszystko już jest w środku.

Stan projektu, w tym rzecz niewygodna

Dane z API GitHuba na 17 października 2026:

  • 46 156 gwiazdek i 3735 forków, repozytorium założone 1 czerwca 2020, kod w Rust,
  • licencja MPL-2.0 — nietypowa w świecie Rusta, o czym w ostatnim akapicie,
  • 1648 otwartych zgłoszeń — liczba duża, choć przy edytorze obsługującym setki języków częściowo naturalna,
  • projekt jest spakowany praktycznie we wszystkich dystrybucjach i menedżerach pakietów, co przy narzędziu instalowanym na cudzych serwerach ma znaczenie praktyczne.

I teraz rzecz, którą trzeba powiedzieć uczciwie, bo w opisach tego edytora się jej nie znajdzie. Ostatnie wydanie to 25.07.1 z lipca 2025 — czternaście miesięcy przed napisaniem tego tekstu. Projekt stosuje wersjonowanie oparte na dacie z rytmem dwóch wydań rocznie (25.01, potem 25.07), co znaczy, że od tamtej pory minęły dwa spodziewane terminy wydawnicze bez wydania. Ostatni commit w gałęzi głównej pochodzi z 23 lipca 2026, czyli sprzed siedmiu tygodni.

Jak to ocenić? To nie jest projekt porzucony — commity z lipca to normalna praca (dodawanie serwerów językowych, aktualizacje gramatyk, rozpoznawanie nowych typów plików), a paczki są dostępne wszędzie. Ale rytm wydawniczy się zatrzymał, a to ma konkretny skutek: jeśli instalujesz z menedżera pakietów, dostajesz kod z lipca 2025, a nie to, co widać w repozytorium. Przy narzędziu, którego główną zaletą jest liczba obsługiwanych języków, czternaście miesięcy różnicy jest odczuwalne — i część osób sięga po budowanie z gałęzi głównej, co przy Rust nie jest problemem, ale jest decyzją.

Liczby, które są całą propozycją wartości

Przejrzałem plik konfiguracji języków dostarczany razem z edytorem i wynik najlepiej tłumaczy, o co w tym projekcie chodzi. Ten jeden plik ma 5657 linii, a w nim:

  • 342 zdefiniowane języki,
  • 303 gramatyki tree-sittera pobierane i kompilowane na potrzeby podświetlania,
  • 190 różnych serwerów językowych przywoływanych przez te języki — od rust-analyzer, gopls i typescript-language-server, przez bash-language-server i ansible-language-server, po rzeczy zupełnie niszowe.

Warto zrozumieć, co to znaczy w praktyce. Nie musisz konfigurować niczego, żeby edytor wiedział, jak podświetlić plik i który serwer językowy do niego uruchomić. Wystarczy, że serwer jest zainstalowany w systemie — resztę edytor już wie. To jest cała różnica wobec składania środowiska z wtyczek: konfiguracja została wykonana raz, przez projekt, dla trzystu języków, i przychodzi razem z plikiem binarnym.

Do tego dochodzi wbudowane polecenie sprawdzające, czy potrzebne narzędzia dla danego języka są w systemie — więc diagnostyka „dlaczego nie mam podpowiedzi" jest jednym wywołaniem, nie wieczorem czytania logów.

README dokłada przy tym zastrzeżenie, które trzeba znać: nie wszystkie języki mają zdefiniowane reguły wcięć, a katalog z zapytaniami tree-sittera pokazuje, dla których je przygotowano. Podświetlanie i serwer językowy to jedno, a automatyczne wcięcia — drugie.

Model edycji odwrócony względem Vima

Autor stawia to w README wprost: model edycji jest bardzo mocno oparty na Kakoune, a nie na Vimie, bo w trakcie prac zgadzał się z większością decyzji projektowych tamtego edytora. To jest rzecz, którą trzeba zrozumieć przed pierwszą próbą, bo inaczej pierwsze pół godziny jest frustrujące.

Różnica sprowadza się do kolejności. W Vimie podajesz najpierw czasownik, potem zakres — „usuń trzy słowa" — i skutek widzisz po wykonaniu. W Helixie najpierw ustanawiasz zaznaczenie, a potem na nim działasz — najpierw wskazujesz trzy słowa i widzisz je podświetlone, dopiero potem je usuwasz.

Konsekwencja jest większa, niż wygląda: widzisz, co zmienisz, zanim to zmienisz. Przy prostych operacjach różnica jest kosmetyczna, ale przy złożonych — przy zmianie w dwudziestu miejscach naraz — decyduje o tym, czy operacja jest sprawdzalna, czy trzeba ją cofać i powtarzać.

Z tego samego modelu wynika druga cecha wymieniona w README: wielokrotne zaznaczenia są tu pojęciem podstawowym, nie funkcją dodaną wtyczką. Zaznaczenie jest zwyczajnie zbiorem zakresów, a każda operacja działa na wszystkich naraz. Kto pracował z wieloma kursorami w nowoczesnym środowisku graficznym, zna ten sposób pracy — tu jest on fundamentem, a nie dodatkiem.

Tree-sitter nie tylko do kolorowania

Największym nieporozumieniem wokół tree-sittera jest traktowanie go jako lepszego podświetlania składni. W Helixie widać, że to znacznie więcej, a spis treści dokumentacji jest tego dowodem: obok podświetlania są tam obiekty tekstowe oraz ruchy świadome składni.

Różnica jest praktyczna. Edytor rozumiejący tylko wyrażenia regularne potrafi zaznaczyć „do końca linii" albo „do najbliższego nawiasu". Edytor mający drzewo składniowe potrafi zaznaczyć funkcję, klasę, parametr, argument wywołania albo całe wyrażenie warunkowe — i przeskoczyć do następnego elementu tego samego rodzaju. To jest ta sama różnica, jaka w naszych narzędziach istnieje między szukaniem tekstu a refaktoryzacją.

Ścieżka rozszerzania jest przy tym otwarta i dobrze opisana — przewodniki w dokumentacji pokazują, jak dodać język wraz z ośmioma rodzajami zapytań tree-sittera: podświetlaniem, zmiennymi lokalnymi, obiektami tekstowymi, wcięciami, wstrzykiwaniem innych języków, znacznikami i kolorowaniem par nawiasów. Innymi słowy: nie da się dopisać wtyczki, ale da się dopisać obsługę języka — i to jest ten rodzaj wkładu, którego projekt oczekuje.

Do tego dochodzą rzeczy z listy funkcji, o których warto wiedzieć, że są w środku, a nie z dodatku: rejestry, otaczanie zaznaczenia znakami, wybieraki do plików i symboli, lista skoków oraz wiersz poleceń. Motywów jest w paczce 218, więc dobieranie kolorów też nie wymaga niczego instalować.

Zaufanie do katalogu roboczego, czyli funkcja, której brak innym

Ta sekcja opisuje mechanizm, który uznaję za najlepszą rzecz w całym tym projekcie, a jednocześnie odpowiedź na zagrożenie, o którym mało kto myśli.

Dokumentacja stawia problem wprost: edytor ma kilka funkcji zdolnych wykonać dowolny kod. Wymienia cztery:

  • serwery językowe,
  • adaptery debugowania,
  • lokalną konfigurację katalogu roboczego — pliki konfiguracyjne leżące w repozytorium,
  • oraz — i to jest wektor, o którym pamięta niewielu — integrację z gitem, czyli filtry i polecenia zapisane w konfiguracji samego repozytorium.

Przełóżmy to na naszą pracę. Klonujesz repozytorium klienta albo pobierasz gałąź z pull requesta od osoby z zewnątrz i otwierasz plik w edytorze. Jeśli edytor ufa temu, co znajdzie w katalogu, właśnie uruchomiłeś cudzy kod na swojej maszynie — z Twoimi kluczami SSH, dostępem do repozytoriów i sesjami w chmurze.

Helix rozwiązuje to jawnym zaufaniem przypisanym do katalogu roboczego, w modelu porównanym w dokumentacji do narzędzia ładującego zmienne środowiskowe z katalogu: raz potwierdzasz zaufanie i edytor pamięta to między sesjami. Domyślne zachowanie jest przy tym przemyślane, a nie zerojedynkowe:

  • Serwery językowe startują automatycznie — z uzasadnieniem: ich pliki wykonywalne pochodzą ze ścieżki systemowej, a nie z repozytorium,
  • Wczytanie konfiguracji z repozytorium oraz zaufanie konfiguracji gita wymaga zgody,
  • Adaptery debugowania nigdy nie startują same, a i tak podlegają temu samemu progowi zaufania.

Sposób pytania też jest zrobiony dobrze. Przy pierwszym otwarciu pliku w nieznanym katalogu pojawia się okno z dwiema opcjami — zaufaj na stałe albo nigdy nie pytaj o ten katalog — a zamknięcie okna bez decyzji zapamiętuje „nieufny na tę sesję", żeby pytanie nie wracało przy każdym kolejnym pliku. W prawym dolnym rogu pojawia się przy tym ostrzegawczy wskaźnik, ale wyłącznie wtedy, gdy zaufanie faktycznie zmieniłoby obserwowalne zachowanie — czyli gdy jest lokalna konfiguracja do wczytania albo serwer, który miałby wystartować.

Ten ostatni szczegół jest tym, co odróżnia dobrze zaprojektowane ostrzeżenie od ostrzeżenia ignorowanego: wskaźnik nie świeci się zawsze, więc kiedy się zapali, coś znaczy. Zaufanie da się przy tym odwołać osobnym poleceniem, a katalog wykluczyć na stałe.

Brak systemu wtyczek — od trzech lat w recenzji

To najważniejsza informacja w tym wpisie i jednocześnie ta, która rozstrzyga o wdrożeniu.

Helix nie ma systemu wtyczek. Nie jest to przeoczenie ani rzecz na później — sprawdziłem stan prac i sytuacja jest zaskakująco jednoznaczna: pull request dodający opcjonalny system wtyczek oparty na dialekcie Scheme'a jest otwarty od 31 października 2023 i zebrał 334 komentarze. To blisko trzy lata w recenzji.

Nie oceniam tej decyzji — dodanie języka skryptowego do edytora jest zobowiązaniem na dekadę i rozumiem ostrożność. Ale trzeba nazwać skutki, bo są konkretne:

  • To, co jest w edytorze, jest wszystkim, co dostajesz. Nie ma sposobu, żeby dodać funkcję, której opiekunowie nie zbudowali,
  • Nie ma ekosystemu — ani rozszerzeń do przeglądania repozytorium, ani klientów baz danych, ani integracji z narzędziami projektowymi, ani paneli plików w wielu wariantach,
  • Rozszerzanie odbywa się przez zewnętrzne procesy: serwery językowe, formatery i polecenia powłoki. Da się dzięki temu zrobić więcej, niż się wydaje, ale zawsze przez proces, nie przez skrypt w edytorze.
Ta sama właściwość jest przy tym źródłem największej zalety Helixa. Brak wtyczek znaczy brak menedżera wtyczek, brak konfliktów wersji, brak zepsutego środowiska po aktualizacji i brak wieczoru na składanie. Edytor działa tak samo na każdej maszynie, bo nie ma czego się różnić. Kto kiedykolwiek naprawiał cudzą konfigurację edytora po aktualizacji, doceni tę wymianę.

Praktyczna konsekwencja dla naszej pracy

Wniosek z dwóch poprzednich sekcji jest jasny i wart wypowiedzenia bez owijania: Helix jest znakomity jako edytor na serwerze i słaby jako główne środowisko pracy — jeśli Twój sposób pracy opiera się na wtyczkach.

Do czego jest właściwym narzędziem: poprawka w konfiguracji na serwerze klienta z podświetlaniem rozumiejącym składnię, przegląd kodu w kontenerze, szybka zmiana w pliku YAML z walidacją z serwera językowego, praca na maszynie, na której nie chcemy nic konfigurować. Instalacja to jedna paczka, a nie procedura.

Do czego nie: zastąpienie środowiska, w którym korzystamy z klienta bazy danych, narzędzi do przeglądania zmian, integracji z systemem zgłoszeń i debugera z interfejsem. Tego się tu nie doda, bo nie ma czym.

Jest jeszcze trzecie zastosowanie, o którym warto pomyśleć osobno: Helix jest bardzo dobrym edytorem do nauki modalnej edycji. Wbudowana pomoc pokazuje dostępne polecenia w trakcie pisania sekwencji, więc nie trzeba uczyć się skrótów na pamięć z kartki, żeby zacząć. Dla osoby w zespole, która chciała spróbować pracy bez myszki i odbiła się od Vima, jest to droga łatwiejsza.

Pułapki

  • Brak wydania od czternastu miesięcy przy rytmie dwóch wydań rocznie. Z menedżera pakietów dostajesz kod z lipca 2025,
  • Brak systemu wtyczek, a jego dodanie wisi w recenzji od października 2023,
  • Model edycji nie jest vimowy. Pamięć mięśniowa z Vima będzie przeszkadzać w pierwszych godzinach, bo kolejność jest odwrócona,
  • Nie wszystkie języki mają reguły wcięć, choć mają podświetlanie,
  • Serwery językowe trzeba mieć w systemie. Edytor wie, którego użyć, ale go nie instaluje — na serwerze produkcyjnym zwykle nie będzie żadnego,
  • Serwery językowe startują domyślnie także w katalogu bez zaufania — uzasadnione tym, że pochodzą ze ścieżki systemowej, ale warto o tym wiedzieć,
  • 1648 otwartych zgłoszeń i siedem tygodni ciszy w gałęzi głównej,
  • Renderer graficzny to eksploracja, nie funkcja — README wspomina o zainteresowaniu własnym rendererem, ale edytor jest terminalowy,
  • Konfiguracja jest plikiem, nie interfejsem — co jest zaletą przy wdrażaniu na wielu maszynach i wadą przy pierwszym kontakcie,
  • Licencja MPL-2.0, nie MIT ani Apache — nietypowo dla projektu w Rust; szczegóły w ostatnim akapicie.

Gdzie to ma sens w naszej pracy

  • Edytor na serwerach klientów. Jedna paczka, zero konfiguracji, podświetlanie rozumiejące składnię tych plików, które faktycznie edytujemy — konfiguracji nginksa, plików Compose, YAML-i i skryptów powłoki,
  • Praca w kontenerach i na maszynach tymczasowych, gdzie przenoszenie konfiguracji edytora nie ma sensu,
  • Przegląd cudzego kodu bez uruchamiania pełnego środowiska — z przechodzeniem do definicji, jeśli serwer językowy jest dostępny,
  • Nauka edycji modalnej dla osoby, która chce spróbować, a nie chce najpierw zbudować konfiguracji,
  • Maszyny o małych zasobach — pojedynczy plik binarny w Rust wobec środowiska opartego na przeglądarce to inna kategoria zużycia pamięci,
  • Plik konfiguracyjny w repozytorium narzędziowym zespołu. Skoro nie ma wtyczek, to cała konfiguracja edytora mieści się w kilku plikach, które da się trzymać w repozytorium i rozwijać jednym poleceniem na nowej maszynie.

Podsumowanie

  • Jeden plik binarny z wbudowanym wsparciem dla serwerów językowych i tree-sittera — nic nie trzeba składać,
  • 342 języki, 303 gramatyki, 190 serwerów językowych w jednym pliku konfiguracyjnym dostarczanym z edytorem,
  • Model edycji z Kakoune: najpierw zaznaczenie, potem operacja — widzisz, co zmienisz,
  • Wielokrotne zaznaczenia są pojęciem podstawowym, nie dodatkiem,
  • Tree-sitter daje obiekty tekstowe i ruchy świadome składni, nie tylko kolorowanie; 218 motywów w paczce,
  • Zaufanie przypisane do katalogu roboczego chroni przed kodem z klonowanego repozytorium — także przed poleceniami z konfiguracji gita,
  • Nie ma systemu wtyczek, a propozycja jego dodania jest w recenzji od października 2023,
  • Brak wtyczek to brak ekosystemu, ale też brak zepsutej konfiguracji — ta wymiana jest sednem tego edytora,
  • Ostatnie wydanie z lipca 2025 przy rytmie dwóch wydań rocznie,
  • Serwery językowe trzeba zapewnić samodzielnie,
  • Nie wszystkie języki mają reguły wcięć,
  • Właściwe zastosowanie: serwery, kontenery, maszyny tymczasowe — nie zastąpienie środowiska opartego na wtyczkach,
  • MPL-2.0, czyli copyleft na poziomie pliku.

Licencja: Helix jest na MPL-2.0 i jest to wybór nietypowy — projekty w Rust stosują zwykle podwójne licencjonowanie MIT albo Apache-2.0, więc warto wiedzieć, czym ta licencja się różni. MPL-2.0 to copyleft działający na poziomie pojedynczego pliku, a nie całego dzieła. Praktycznie znaczy to, że zmodyfikowanie pliku pochodzącego z tego projektu i rozpowszechnienie wyniku wymaga udostępnienia tego pliku na tej samej licencji — ale kod, który tylko z projektem współpracuje albo jest z nim łączony jako osobne pliki, pozostaje na naszych warunkach. To układ pośredni między licencją permisywną a GPL: znacznie łagodniejszy niż GPL, bo nie „zaraża" całej aplikacji, i wyraźnie bardziej wymagający niż MIT, bo nie pozwala po cichu zamknąć poprawek w zmodyfikowanych plikach. Dla typowego użycia — czyli zainstalowania edytora i pracy w nim — nie ma to żadnego znaczenia: samo korzystanie z programu nie rodzi obowiązków w żadnej z tych licencji, a konfiguracja i motywy, które napiszemy, są naszymi danymi, nie dziełem pochodnym. Znaczenie pojawia się w dwóch sytuacjach: przy zbudowaniu i rozpowszechnieniu własnej, zmienionej wersji edytora (na przykład z łatką dla klienta) oraz przy wykorzystaniu fragmentów kodu Helixa we własnym narzędziu — i wtedy obowiązek dotyczy plików, które ruszyliśmy. Osobno warto pamiętać, że gramatyki tree-sittera i serwery językowe są odrębnymi projektami z własnymi licencjami, pobieranymi albo instalowanymi niezależnie; przy audycie zależności u klienta to one, a nie sam edytor, wygenerują większość pozycji na liście.