2021-12-14 / Bartłomiej Kurek
Od czego zacząć? #3 (edytory, środowiska)

Na pracę z kodem i systemami składają się różne procesy, m.in:

  • edycja kodu
  • budowanie
  • uruchamianie/testowanie
  • wdrożenia, aktualizacje
  • monitoring

W tym artykule poruszam zagadnienie edycji kodu i staram się zestawić je z pozostałą częścią procesów. Przytaczam również krótki rys historyczny rozwoju w dziedzinie edytorów i środowiska operacyjnego, co może rzucić nieco więcej światła oraz pokierować naszymi wyborami i kierunkami w zakresie zdobywania umiejętności.

Edytor

Kod

Kod źródłowy programów to tekst. Edytujemy go edytorem potrafiącym edytować pliki tekstowe. Edytory programistyczne charakteryzują się wsparciem dla edycji tekstu zapisanego w językach programowania. Języki programowania mają swoją składnię. Składnia obejmuje słowa kluczowe, znaki, typy danych, metadane. Dobry edytor kodu to taki, który umożliwia nam sprawne przeglądanie, nawigację w kodzie i jego edycję. Edytor powinien zapewniać pracę wolną od zbędnych dystrakcji. Dobrze kiedy zapewnia nam sensowne podpowiadanie składni, pomoc kontekstową. Najlepiej kiedy nie robi tego nachalnie (dystrakcje), ani nie blokuje naszej pracy.

Procesy

Zupełnie innym podzbiorem działań jest uruchamianie kodu, czy to w celach testowych, czy też po prostu uruchamianie tworzonych programów oraz usług pomocnicznych. Mnogość i złożoność procesów zachodzących w trakcie pracy nad oprogramowaniem jest wysoka. Oprócz samego kodu programów - czy to w pojedynczym pliku, czy w wielu plikach modułów - często pracujemy z kodem testów jednostkowych oraz specjalistycznych narzędzi (np. debuggery, profilery).

Środowiska

Istnieją edytory kodu oraz zintegrowane środowiska programistyczne łączące edycję kodu z pozostałymi procesami. Środowiska programistyczne dostarczają własną automatyzację procesów, ale najczęściej uruchamiają zewnętrzne, dedykowane tym procesom programy, ze względu na skalę dziedzinową tychże programów.
To jaki tryb pracy wybieramy - edytor, czy zintegrowane środowisko - powinno zależeć od naszych celów i umiejętności. Użycie samych edytorów zmusza nas niejako do zaznajomienia się z dedykowanymi programami obsługującymi dany język (interpreter, kompilator, debugger, profiler, itp.). Osobiście uważam, że szybciej osiągniemy wyższy poziom wiedzy zdając się na ten właśnie tryb pracy (edytor + zewnętrzne dedykowane poszczególnym komponentom narzędzia). Dodatkowo te narzędzia podstawowe możemy stosować wszędzie, automatyzować po swojemu, wedle własnych preferencji i wymagań, a przy okazji poznajemy ich możliwości, specyfikę, dokumentację. Z drugiej strony - środowiska zintegrowane poniekąd dają możliwość przystąpienia do pracy "od razu". Po uruchomieniu środowiska mamy je wstępnie przygotowane do edycji kodu, mamy guziki "play", "stop", które coś standardowego robią.

Początkujący wybierają najczęściej środowiska zintegrowane ze względu na niższą barierę wejścia - szybciej uzyskują pierwsze rezultaty, co z kolei utrzymuje poziom motywacji i determinacji. W mojej opinii jednak wadą w tym podejściu bywa fakt, iż zdając się na tę automatyzację wiemy jedynie, że po kliknięciu "start/stop" dzieje się "coś", czego nie dostrzegamy, wcale nie rozumiemy, a najczęściej nie zdajemy sobie sprawy, że jest to kluczowe dla zrozumienia istoty rzeczy, do której zmierzamy. Zatem ważne jest przy tym trybie pracy zaznajomienie się chociaż w minimalnym stopniu z ogólną naturą narzędzi podstawowych (jakie są i co robią).

Środowiska zintegrowane nastawione są na automatyzację procesów, których jesteśmy świadomi. Jeśli nie jesteśmy świadomi procesów, zależności, konieczności konfiguracji, to środowiska te mogą prowadzić do dystrakcji, ograniczeń i frustracji. Zaczynają pojawiać się ostrzeżenia, monity, utrudnienia. Jednym słowem: dystrakcje. Zamiast kodować, zajmujemy się środowiskiem, wyrabiamy sobie i utrwalamy też znane ścieżki do osiągnięcia celu w tym środowisku. Ścieżek tych jednak często nie będziemy mogli zastosować w innym środowisku (podstawowym). Pojawia się wtedy myśl: "skoro nie ma w moim IDE, to znaczy, że się nie da".

Tradycyjne edytory też nie są bez wad. O ile w środowiskach zintegrowanych raczej wszystko działa, jest to, co jest i nie ma innego wyboru, to w tradycyjnych edytorach również mogą pojawiać się drobne niedogodności, albo mnogość możliwości rozwiązań. W IDE zdajemy się na to co jest, w tradycyjnym podejściu przystosowujemy narzędzia do własnych preferencji, co z kolei może wymagać więcej umiejętności, nakładu czasu i pracy.

Zintegrowane?

Warto wrócić tutaj do słowa "zintegrowane" w nazwie "środowisko zintegrowane". Co to oznacza? Dla mnie, słowo to nie jest jednoznaczne.
Moim podstawowym środowiskiem jest zestaw narzędzi systemowych, które wspierają w zasadzie wszystko. Te narzędzia już posiadam, używam ich na co dzień, umiem je wykorzystać, są klockami, z których buduję własne, większe klocki. Środowiska programistyczne mogą je integrować, jednak większość środowisk zintegrowanych dostarcza swoje odpowiedniki funkcjonalności już przeze mnie posiadanej. Te "odpowiedniki" nie mają tego samego interfejsu, tych samym możliwości, a zatem są to "zastępniki", dostępne jedynie w obrębie danego programu IDE, a często jeszcze ograniczone do pracy z jednym językiem programowania, do którego to środowisko powstało.

Przykładowo:
W systemie mam programy, które umieją sortować, zliczać znaki, linie, podmieniać ciągi w napisach/plikach, przeszukiwać skompresowane archiwa, przetwarzać strumienie danych w locie, itd. Umiem ich używać, wykorzystuję je również jako "basic buliding blocks" do tworzenia własnych programów/skryptów. Idealnym dla mnie środowiskiem zintegrowanym jest zatem takie, które istniejący już potencjał wykorzystuje, a nie zastępuje swoimi odpowiednikami, które - de facto - uniemożliwiają wykorzystywanie już zdobytych przeze mnie wiedzy i umiejętności.

Każdy ma swoje preferencje i sposoby pracy. W końcu to "Personal Computing". Pracujemy tak jak umiemy i oczekujemy możliwości wykorzystania posiadanych umiejętności. Różne rozwiązania dają nam różne przyzwyczajenia. Jeśli ja w systemie operacyjnym mam program "sort", to oczekuję, że mój edytor kodu będzie w stanie wysłać zaznaczony fragment tekstu do takiej komendy i zwrócić jej wynik lub wstawić go bezpośrednio w miejsce, w którym znajduje się kursor w edytorze. Bez względu na to czy to sortowanie, przekształcanie, filtrowanie, zliczanie kodu/tekstu, mechanizm jest ten sam: wyślij zaznaczony fragment do komendy X. To pozwala mi również na rozszerzanie możliwości edytora przez stosowanie własnych programów/skryptów. Dlatego jestem zdania, że zawsze warto mieć możliwość uciekania się do "prymitywu", z którego abstrakcje powstają.

Narzędzia

Kiedy w środowiskach zaintegrowanych klikamy "buduj", lub "uruchom", to środowiska te uruchamiają zewnętrzne programy. PyCharm nie implementuje interpretera Python, a jedynie go uruchamia. Visual Studio uruchamia kompilator czy debugger, które są osobnymi programami. Możemy zdać się na wykorzystanie tej automatyzacji, jednak warto pamiętać o tym, że pod spodem też coś jest, a często to co jest pod spodem, jest istotą systemu, z którym pracujemy.

Przesłanki

Cele

Bez względu jednak na to jakie środowisko wybieramy - powinniśmy być świadomi zarówno jego zalet, jak i wad. Każde rozwiązanie ma swoje plusy i minusy.
Najważniejsze zatem jest wiedzieć czego od środowiska programistycznego oczekujemy. W nowoczesnych rozwiązaniach mamy często integrację obejmującą nawet wideokonferencje, czy sklepy z pluginami. Wszystkie narzędzia do czegoś służą i powstały w jakimś celu. Najważniejszym wydaje się być zatem świadome określenie naszych własnych celów i podążanie za nimi.

Zakres zastosowania

Edycję kodu/konfiguracji czasem realizujemy poza "wygodnym środowiskiem". Programy uruchamiamy często w zupełnie innym środowisku docelowym niż nasz edytor/IDE. Procesy testowania oprogramowania automatyzujemy w zewnętrznych środowiskach (Continuous Integration), gdzie platformą jest przykładowo kontener Docker. Im więcej tych procesów, tym więcej zależności i koniecznej konfiguracji. Wydaje się zatem oczywistym, że istnieje gdzieś limit integracji procesu wytwarzania oprogramowania z procesami testowymi, czy po prostu uruchamiania programów będących rezultatem naszej pracy. Myślę, że tutaj właśnie trzeba sobie znaleźć rozsądną granicę rozdzielającą te odrębne fazy. Środowiska zintegrowane są zazwyczaj mocno zamknięte w sobie samych, więc wszystkie zewnętrzne operacje muszą doimplementować wewnątrz swojego "workflow", opakować zewnętrzne narzędzia, stworzyć nowe mechanizmy ich konfiguracji możliwe do użycia w tym "workflow".

Rosnąca złożoność: przykładowo uruchamiasz program "w chmurze" i chcesz go debugować. Oczywiście możesz, ale musisz skonfigurować połączenie do docelowego systemu "w chmurze", wliczając w to dostęp sieciowy i bezpieczeństwo. Oczywiście - do tego wszystkiego wykorzystane zostaną zewnętrzne mechanizmy. Zmierzam tutaj do tego, że - w mojej opinii - kluczowymi są wiedza o możliwościach tych zewnętrznych narzędzi podstawowych oraz umiejętność ich wykorzystania do osiągnięcia konkretnego celu. Narzędzia podstawowe działają wszędzie i zawsze, nic "nie wiedzą" o istnieniu naszych różnych środowisk, realizują konkretne, dedykowane zadania, robią to dobrze, spójnie i w pełni. W przypadku środowisk zintegrowanych sytuacja jest odwrotna - nasze środowisko musi wiedzieć wszystko o wszystkim. A jeśli czegoś nie umie lub nie spełnia wszystkich możliwości danego narzędzia podstawowego, to może zacząć być problematyczne. Ta problematyczność to właśnie dystrakcje.

Od historii do nowoczesności

Kiedyś nie było monitorów, output programów/systemów lądował na taśmie, czy wydruku papierowym. Połączenie tego wyjścia z wejściem (klawiaturą, urządzeniem znakowym) było terminalem. Stąd mamy w systemach "terminale". Z biegiem czasu i rozwojem technologii pojawiły się edytory, które umożliwiały edycję większych buforów zawierających tekst. Jednym z takich edytorów był TECO (Text Editor and Correcor).
Zawierał on swój wbudowany język programowania umożliwiający automatyzację powtarzalnych czynności.
Posiadał też osobne tryby: wprowdzania znaków (edycja tekstu) oraz tryb wywoływania poleceń. Konsekwencje tego widzimy do dzisiaj. Od tamtych czasów pojawiły się w UNIX m.in. dwa główne edytory: Emacs oraz vi. Emacs powstał jako zbiór makr do obsługi TECO, a vi to odrębny edytor, który jednak powtarza rozdzielenie trybów edycji i trybu komend. Oba edytor są rozwijane od roku 1976 (45 lat) i są najpopularniejszymi edytorami używanymi powszechnie.

Emacs ma wszystko, co można sobie wyobrazić, a vi jest wszędzie. Są to edytory, które wykorzystują istniejący potencjał samego środowiska. Emacs to w zasadzie rozszerzalny system operacyjny (można tworzyć/modyfikować jego zachowanie w skryptach (język LISP)). Vi również implementuje mnóstwo funkcji. Konsekwencją popularności obu tych edytorów jest np. to, że w interaktywnych shellach (np. bash) mamy dwa odrębne sposoby pracy w terminalu: sterowanie z klawiatury jak w Emacs, lub jak w vi. Domyślnie w shellach ustawiony jest tryb emacs. Bagaż tych doświadczeń jest niesiony oczywiście dalej - w zasadzie każde środowisko implementuje okrojone tryby skrótów klawiszowych zgodnych z Emacs oraz vi. Nawet w Firefox można ustawić skróty klawiszowe zgodne z Emacs.

Edytory te mają wiele klonów i wersji. Oba działają w terminalu i mają swoje implementacje okienkowe. Niemniej, w każdym z nich możemy wykorzystać potencjał środowiska Unix oraz pracować na swojej maszynie, w sesji zdalnej, na maszynie wirtualnej, czy w kontenerze. Są to jednak edytory, które wymagają poświęcenia czasu na naukę ich obsługi. Kiedy już opanujemy któryś z nich, świat innych edytorów staje się dla nas niepojęty.

Nieco zawyżona bariera wejścia w świat wygodnej pracy w tych edytorach sprawiła, iż pojawiły się nowoczesne alternatywy, które dzisiaj obserwujemy w postaci środowisk zintegrowanych, czy edytorów opartych o przeglądarkę internetową (rozwiązania oparte o Electron). Istotą różnicy pomiędzy pracą w "tradycyjnych" edytorach, a w tych nowoczesnych środowiskach jest właśnie możliwość integracji ze środowiskiem operacyjnym. Nowoczesne środowiska w gruncie rzeczy odbierają nam istniejące możliwości, a w zamian implementują po swojemu swoje odpowiedniki, niedostępne dla innych środowisk.

Niemniej, platformami wdrożeniowymi dla usług są serwery. W serwerach nie ma klawiatur, monitorów, myszek. W świecie serwerów/kontenerów wracamy do poziomu terminala i mierzymy się z wyzwaniami, które "dawno, dawno temu" posiadały już solidne, sprawdzone, efektywne rozwiązania. Dlatego też wyżej starałem się zwrócić uwagę na fakt, iż edycja i procesy poboczne to dwa odrębne światy.
W tym momencie można by jednak rzec, że starsze rozwiązania są uniwersalne i zintegrowane z platformą. Działają wszędzie, zawsze, pozwalają wykorzystać istniejący potencjał środowisk, w których dzisiaj pracujemy i dzięki którym realizujemy usługi.

Reasumując: bez względu na to jakie środowisko programistyczne wybierzemy, ostatecznie zetkniemy się z rzeczywistą platformą, a im lepiej znamy samą platformę, tym większy jest nasz potencjał. Nie należy negować jakichkolwiek środowisk, każde z nich jest użyteczne, spełnia rożne wymagania, pomaga, automatyzuje, daje się przystosować i rozszerzać. Nie wszystkich jednak użyjemy wszędzie.

Krótki przegląd edytorów/środowisk

GNU EMacs

Emacs możemy użyć do wszystkiego. Do każdego języka programowania, do obsługi email, kalendarzy, przeglądania internetu, tworzenia dokumentów, obliczeń, ... Nie sposób wymienić możliwości. Emacs zawiera wszystko, a czego nie zawiera, to będzie zawierał. Używają go m.in.:

  • Richard Stallman (GNU, autor GCC i główna postać stojąca za projektem GNU Emacs)
  • Guido Van Rossum (autor Python)
  • Linus Torvalds (autor Linux)
  • Theo Da Raadt (leader projektu OpenBSD)
  • Donald Knuth (autor TeX i ważnych książek)
  • Jamie Zawinsky
  • Mark Zuckerberg

i niepoliczalna rzesza osób. Nie jest to jednak edytor dla każdego.

vi

Vi jest wszędzie. Przykładowo w systemie minix2, który jest głównie systemem edukacyjnym, oprócz minimalnego kompilatora C (Amsterdam C Compiler) znajdziemy dwa edytory: mikroklon emacs zwany "elle", oraz "vi". Vi jest równie popularny jak Emacs. Można go użyć do edycji wszelkiego kodu i dokumentów. Używają go ludzie, którzy nie chcą używać Emacs. Są też ludzie, którzy połączyli oba rozwiązania i używają Emacs np. z viper mode.

Tak jak i Emacs - nie jest to edytor dla każdego.

Proste edytory konsolowe

Spośród małych, przydatnych edytorów konsolowych można wymienić m.in.: pico (ultraprzenośny), mg (micro gnu - mini klon emacs, po prostu edytor), nano, joe. Umiejętność obsługi któregokolwiek z nich umożliwi nam edycję "na szybko" plików konfiguracyjnych, wprowadzenie drobnych poprawek, itp. Nie są to może edytory do codziennego użytku, choć z "mg" korzystam bardzo często (jest mały i ma to co ma mieć minimalny klon emacs).

Inne

Istnieje wiele innych edytorów. Praktycznie każdy "notatnik" w Linux zawiera wsparcie w postaci kolorowania składni różnorakich językow programowania i formatów. Istnieją też nieco bardziej dedykowane edytory jak: Geany, CodeLite, Gedit, Brackets.
Popularnym edytorem wśród programistów jest również SublimeText. Wiele osób chwali ten edytor, sam nie używałem. Myślę jednak, że warto zamieścić tutaj link. Edytor wymaga zakupu licencji, posiada wersję ewaluacyjną.

Środowiska

Python

  • Thonny
    Małe i dobre środowisko dla początkujących. Napisane w Python, przeznaczone dla Python, robi co ma robić, posiada debugger, przyciski play/stop, nie wprowadza dystrakcji. Powstało na Uniwersytecie w Tartu (Estonia), rozwijane jest przy udziale Raspberry Pi Foundation.
  • Spyder
    Zintegrowane środowisko Python nastawione na dziedzinę "Scientific Python", wizualizację danych, itd.
  • Eric
    Zintegrowane środowisko Python napisane w Python.
  • PyCharm
    Zintegrowane środowisko Python. Posiada wersję Community oraz płatną. Jedno z najpopularniejszych. Ma wiele integracji, zajmuje 476mb przed rozpakowaniem, napisane w Javie (to jest to samo co "IntelliJ IDEA" dla języka Java, ta sama czeska firma: jetbrains.com). Dla wielu podstawowe narzędzie pracy, dla innych wyskakujące żaróweczki, java, czeski film.

C/C++

  • Code::Blocks - dosyć populane, przenośne środowisko zintegrowane dla C/C++.
  • QTCreator - przenośne, dobre do pracy z biblioteką QT
  • CLion - klon IntelliJ IDEA i takoż PyCharm, z tej samej firmy. Płatne. Nic więcej nie umiem powiedzieć.

Ogólne

  • GNU Emacs
    Do wszystkiego co chcemy i czego jeszcze nie chcemy.
  • Visual Studio
    Windows-only, do projektów w rożnych językach. Można w nim tworzyć oprogramowanie w C, C++, Python, C#, ekosystemie .NET, itd.
  • Visual Studio Code
    Nazwa nieco myląca. Jest to nowoczesne, uniwersalne środowisko oparte o Electron (czyli przeglądarkę Chromium). Działa na Linux/Windows/MacOS. Stworzone w oparciu o HTML/Javascript/TypeScript/CSS, a zatem po prostu coś a'la strona internetowa. Nic więcej nie umiem o nim powiedzieć.
  • Atom
    W zasadzie to samo co Visual Studio Code, ale od GitHub a nie od Microsoftu. Chociaż... GitHub obecnie należy do Microsoft.

Podsumowanie

Jeśli stawiasz pierwsze kroki, wybierz prosty edytor lub podstawowe środowisko. Unikniesz zagłębiania się w zbędne konfiguracje rzeczy, których najprawdopodobniej i tak nie użyjesz jeszcze przez długi okres czasu. Jeśli szukasz uniwersalnego edytora "na lata", to rozważ zaznajomienie się z emacs lub vi. Bez względu jednak na wybrany edytor/środowisko nie unikaj zapoznawania się z podstawowymi narzędziami, gdyż te i tak będą zawsze i wszędzie.