Dynamiczne tworzenie równoległych wątków

Dynamiczne tworzenie równoległych wątków
AS
  • Rejestracja:prawie 8 lat
  • Ostatnio:8 miesięcy
  • Postów:48
2

Ja jak potrzebuję wątków to idę po prostu po najmniejszel lini oporu i robię to tak.
Najpierw odpalam wątek ,który robi za kierownika (uruchamia pracowników i czeka aż skończą pracę). Celowo używam najpierw wątka kierownika aby nie blokować głównego watku aplikacji.

Kopiuj
type
  TSupervisorThread = class(TThread)
  private
    { Private declarations }
    CopiedProgress:integer;
  protected
    procedure Execute; override;
  end;

type
  TWorkerThread = class(TThread)
  private
    { Private declarations }
    ThreadIndex:integer;  
  protected
    procedure Execute; override;
  end;

var Progress:integer;

procedure TSupervisorThread.Execute;
var x:integer;
    WaitStatus,Threads:cardinal;
    WorkerThreadArray:array of TWorkerThread;
    WorkerThreadHandleArray:array of THandle;
begin

 Threads:=16; //np. 16 wątków 

  SetLength(WorkerThreadArray,Threads);
  SetLength(WorkerThreadHandleArray,Threads);
  
   for x:=0 to Threads-1 do
  begin
   
    WorkerThreadArray[x]:=TWorkerThread.Create(True);
    WorkerThreadHandleArray[x]:=WorkerThreadArray[x].Handle;
    WorkerThreadArray[x].FreeOnTerminate:=false;
    WorkerThreadArray[x].Priority:=tpNormal;
    WorkerThreadArray[x].ThreadIndex:=x;
    WorkerThreadArray[x].Resume;

  end;

  repeat
    WaitStatus:=WaitForMultipleObjects(Threads, @WorkerThreadHandleArray[0], True, 100);
    Synchronize(GetProgress);
    if Terminated=true then for x:=0 to Threads-1 do 
begin
    WorkerThreadArray[x].Terminate;
    if WorkerThreadArray[x].Suspended=true then WorkerThreadArray[x].Resume;
end;

  until WaitStatus<>WAIT_TIMEOUT;

  for x:=0 to Threads-1 do if Assigned(WorkerThreadArray[x])=true then FreeAndNil(WorkerThreadArray[x]);
  

end;

procedure TSupervisorThread.GetProgress;
begin
     CopiedProgress:=Progress; // albo pokazać gdzieś w GUI 
end;

procedure TWorkerThread.Execute;
begin
     {jakaś praca tutaj}
    Synchronize(UpdateProgress)
     
end;

procedure TWorkerThread.UpdateProgress;
begin
     Inc(Progress);
end;

edytowany 2x, ostatnio: flowCRANE
flowCRANE
Mówi się po linii najmniejszego oporu. :P
JM
Może się mówi, ale i tak pan Kirchhoff się w grobie przewraca. Nie wiem kto to urobił
Pepe
  • Rejestracja:ponad 22 lata
  • Ostatnio:34 minuty
  • Postów:496
0

Wygląda ciekawie!
A jak rozdzielić pracę na poszczególne wątki?


AS
  • Rejestracja:prawie 8 lat
  • Ostatnio:8 miesięcy
  • Postów:48
0

Najpierw trzeba przygotować listę rzeczy do zrobienia. Ja używam zwykłego TStringList.

Przed uruchomieniem wątków roboczych robisz

Kopiuj
TaskList:=TStringList.Create; //TaskList jest zadeklorawana globalnie aby wszystkie wątki miały do niej dostęp podczas synchronizacji

TaskList.Add(FilePath) //ścieżka np. do jakiegoś pliku ,który trzeba przekonwertować w wątku

Dodajemy procedure CheckTaskList ,w której będziemy pobierać sobie coś do roboty. Lokalnie w wątku również deklarujemy sobie zmienną do której będziemy kopiować zadanie.

Kopiuj
type
  TWorkerThread = class(TThread)
  private
    { Private declarations }
    ThreadIndex:integer;  
    Task:string;
    procedure CheckTaskList;
  protected
    procedure Execute; override;
  end;

Dalej chyba już powinno być już zrozumiałe,

Kopiuj
procedure TWorkerThread.Execute;
begin

   repeat 

      Synchronize(CheckTaskList); 
      if Task<>'' then 
      begin
           {jakaś praca tutaj}
           Synchronize(UpdateProgress);
      end;

    until (Task='') or (Terminated=true);

end;
Kopiuj
procedure TWorkerThread.CheckTaskList;
begin

    if TaskList.Count>0 then
    begin
         Task:=TaskList.Strings[0];
         TaskList.Delete(0);
    end
    else Task:='';

end;
edytowany 11x, ostatnio: Atak_Snajpera
Pepe
  • Rejestracja:ponad 22 lata
  • Ostatnio:34 minuty
  • Postów:496
2

W końcu udało się zaimplementować prosty system obsługi wątków, zgodnie z sugestiami z tego wątku (oraz innego, który traktował o klasach WMI)...
Jeśli ktoś chce zobaczyć efekty, proszę bardzo (patrz załącznik). Wątki śmigają i można zobaczyć co w danej chwili jest robione...
Pierwsze uruchomienie trwa nieco dłużej, ponieważ pobierane są wszystkie klasy WMI, później są odczytywane z cache...

Program jest oczywiście dopiero w fazie początkowej (jest częścią większego projektu). Ma za zadanie wyświetlić najważniejsze informacje o sprzęcie oraz systemie. Jego istotą NIE jest wyświetlenie szczegółowych informacji, tylko podstawowych, które pozwolą zwykłemu użytkownikowi zorientować się na czym de facto pracują i dlaczego ten sprzęt taki słaby :P

Jeśli ktoś ma jakieś uwagi, chętnie wysłucham. Mogą być błędy (z pewnością będą :)). Do zrobienia mam Ustawienia aplikacji, Tworzenie Raportu (txt, html) oraz system obsługi wersji językowych.

Ps: Jeśli AV zgłosi pretensje, nie przejmować się. Plik jest czysty (od dawna próbuję znaleźć skuteczną metodę, żeby programy AV nie zgłaszały nieistniejących zagrożeń w pliku generowanym przez Delphi... ale to walka z wiatrakami. Wydaje się, że jedyną skuteczną metodą jest zgłaszanie false-positive bezpośrednio producentowi). Być może wykupienie podpisu cyfrowego (ale to jest za drogie i nie ma gwarancji).

-Pawel

SysInfo.zip


edytowany 1x, ostatnio: Pepe
GS
Sysinfo dobra robota ... :)
Pepe
Dzięki! Aktualnie pracuję nad raportem HTML... ma być ładny, przejrzysty i prosty... zobaczymy co wyjdzie :P
GS
@Pepe: zainstalowałem "ULTIMATE FILE MANAGER 7.9 FULL", dobra robota :) ale mam pytanie, bo pogubiłem się w opcjach, czy da się tak go skonfigurować aby wyszukiwanie plików w folderze działało na 'Alt+letter' ?
Pepe
Czy chodzi Ci o Quick Search? Wywołujesz go skrótem Ctrl+Alt + Litera (lub prawy Alt + Litera). Co do konfiguracji, to F1 -> Quick Search (a funkcjonalność tę można przypisać do dowolnego skrótu używając polecenia cm_ShowQuickSearch, jeśli dobrze rozumiem o co ci chodzi...)
GS
@Pepe: dziękuję. Tak, to miałem na myśli. Z prawym Altem działa, ale z Total Commandera mam nawyk że Quick Search działa jako Left Alt + litera.
AS
  • Rejestracja:prawie 8 lat
  • Ostatnio:8 miesięcy
  • Postów:48
1

Miodzio.Bardzo estetycznie wykonany program. Dobrze że używasz poprawnych jednostek binarnych (MiB,GiB...) zamiast MB,GB i traktowanie ich niepoprawnie jako MiB,GiB.
Taka pierdoła z mojej strony. Do wyświetlania np. użycia procesora nie używałbym standardowego ProgressBara bo to dziwnie wygląda. Użyłbym po prostu czegoś co nie generuje tej typowej animacji z "błyskiem".

Co do plucia się antywirków to znam to. Wystarczy że spakujesz .exeka np. głupim upx'em i Od razu jesteś traktowany jak "haksior"

edytowany 2x, ostatnio: Atak_Snajpera
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 9 godzin
  • Lokalizacja:Tuchów
  • Postów:12165
0
Atak_Snajpera napisał(a):

Miodzio.Bardzo estetycznie wykonany program. Dobrze że używasz poprawnych jednostek binarnych (MiB,GiB...) zamiast MB,GB i traktowanie ich niepoprawnie jako MiB,GiB.

W wielu miejscach jednostki używane są poprawnie, ale co najwyżej nieintuicyjnie. Najważniejsze jest to, aby używać prawidłowych obliczeń względem wybranej skali — dzielenia np. przez 1000 w przypadku MB oraz przez 1024 w przypadku MiB.

Taka pierdoła z mojej strony. Do wyświetlania np. użycia procesora nie używałbym standardowego ProgressBara bo to dziwnie wygląda. Użyłbym po prostu czegoś co nie generuje tej typowej animacji z "błyskiem".

Już kiedyś pokazywałem użytkownikowi @Pepe jak zrobić wykres zużycia, taki sam jak ma Win10. Łatwe to i ładne. Ale to był tylko test — we właściwej kontrolce takiego wykresu użyłbym antialiasingu. ;)

Wystarczy że spakujesz .exeka np. głupim upx'em i Od razu jesteś traktowany jak "haksior"

No to nie pakuj, bo to żadnego sensu nie ma, a tylko zwiększasz prawdopodobieństwo wystąpienia problemów u użytkownika końcowego.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 1x, ostatnio: flowCRANE
Pepe
  • Rejestracja:ponad 22 lata
  • Ostatnio:34 minuty
  • Postów:496
0

@Atak_Snajpera: Dzięki. UPX'a nie używam, właśnie z uwagi na fakt, że wtedy problemy są murowane... Rozmiar exe mi nie przeszkadza (i tak Delphi tworzy bardzo duże pliki wynikowe - ale w zamian dostaję wygodę i prostotę). A być może wydzielę obrazki (i inne zasoby) do osobnego pliku dll.

@furious programming: Użytkownik @Pepe pamięta bardzo dobrze i do dzisiaj jest wdzięczny za pomoc :) Jak już pisałem, jesteś dla mnie wzorem forumowicza - zawsze chętny od pomocy i zawsze przygotowany. Twoje posty są merytoryczne i pomocne.
Zaimplementuję kiedyś taką funkcjonalność (ale nie wiem czy w programie, bo w sumie ten akurat program jest dla mniej doświadczonych użytkowników... ale mam w planach stworzyć coś ala widżet na pulpit...


AS
  • Rejestracja:prawie 8 lat
  • Ostatnio:8 miesięcy
  • Postów:48
0

Dobre antivirki takie jak ten Microsoftowy automatycznie rozpakowują exeki przed analizą. Każdy inny ,który tego nie potrafi to przykład totalnej amatorki ze strony programisty i taki wyrób programopodobny nie jest warty instalowania. Ja używam upxa bo lubię jak binarki są małe. Taka stara szkoła...

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 9 godzin
  • Lokalizacja:Tuchów
  • Postów:12165
1
Atak_Snajpera napisał(a):

Dobre antivirki takie jak ten Microsoftowy automatycznie rozpakowują exeki przed analizą. Każdy inny ,który tego nie potrafi to przykład totalnej amatorki ze strony programisty i taki wyrób programopodobny nie jest warty instalowania.

Tyle że to nadal nie zmienia faktu, że sam sobie tym rzucasz kłody pod nogi, nie mając żadnego sensownego powodu. Im więcej użytkowników, którym wyskoczą powiadomienia o zagrożeniach (nieistotne czy poprawnie czy nie), tym gorzej dla Ciebie i Twojego oprogramowania. Ja wiem, że nie każdy chce wydawać kasę na podpis cyfrowy i zadbać o każdy szczegół, aby system nie traktował programu z podejrzliwością.

Ja używam upxa bo lubię jak binarki są małe. Taka stara szkoła...

To nie jest sensowny powód — taka „stara szkoła” miała sens 20 lat temu, a od wielu lat rozmiar plików wykonywalnych nie ma większego znaczenia, bo przeciętnemu użytkownikowi ani nie brakuje miejsca na dysku i pamięci RAM, ani też nie cierpi z powodu zbyt wolnego łącza internetowego. Poza tym łącze to i tak nieistotny element, bo program jeśli już to pobiera raz i z głowy.

Dziś pakowanie jakichkolwiek plików za pomocą UPX-a i podobnych narzędzi praktycznie w ogóle nie ma sensu. Być może są specyficzne przypadki, aby było to uzasadnione, ale we wszelkich typowych zastosowaniach uzasadnienia nie ma. Tym bardziej, że takie bezcelowe pakowanie powoduje dodatkowe problemy, które łatwo jest uniknąć po prostu nie używając tego typu narzędzi. No chyba, że lubisz się tłumaczyć użytkownikom z tego, dlaczego antywirusy blokują Twój program, to spoko. ;)


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 3x, ostatnio: flowCRANE
AS
  • Rejestracja:prawie 8 lat
  • Ostatnio:8 miesięcy
  • Postów:48
0

Antivirki i bez tego się często plują ,więc jeden pies. Nieodpowiednia faza księżyca i jesteś "keyloggerem/mallware/spyware/bitcoin minerem...". Dobrze że chociaż co raz więcej ludzi rezygnuje z tych głupich zewnętrznych często problematycznych anitirków i korzysta z wbudowanego w windows. Ten przynajmniej nigdy nie ma problemów z moimi programikami (pakowanymi czy nie).

edytowany 1x, ostatnio: Atak_Snajpera
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 9 godzin
  • Lokalizacja:Tuchów
  • Postów:12165
0

Heurystyka nie daleka od doskonałości i z tym niewiele można zrobić. Jednak jeśli ma się możliwość wykluczenia pewnej ilości fałszywych podejrzeń, to warto z niej skorzystać — tym bardziej, jeśli ta możliwość oznacza po prostu nie robienia niczego z plikiem wykonywalnym.

Natomiast niższy rozmiar pliku wykonywalnego można osiągnąć w sposób bezpieczny, po prostu usuwając z programu rzeczy niepotrzebne (np. nieużywane moduły z kodu źródłowego). Choć to i tak nie ma żadnego znaczenia, bo taka modułowa narośl nie waży więcej niż miegabajt. Tak więc wszelkie dodatkowe zabiegi mające na celu zmniejszenie rozmiaru pliku wykonywalnego po prostu nie mają żadnego sensu w dzisiejszych czasach.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 2x, ostatnio: flowCRANE
Pepe
  • Rejestracja:ponad 22 lata
  • Ostatnio:34 minuty
  • Postów:496
0

Hey,
Jakiś czas temu pokazywałem jak program SysInfo działa (do gromadzenia informacji wykorzystuje WMI oraz wątki).

Od tego czasu udało mi się zaimplementować tworzenie raportu w formacie HTML (jeszcze chcę zrobić TXT). Dodałem również opcje (że można sobie poustawiać pod siebie). Aha, jeszcze dodam spis tresci (content/index) do raportu, żeby móc szybko przeskoczyć do interesującego nas działu).

W przyszłości jakieś wykresy i trochę info o programach (typu zainstalowane programy, działające procesy, etc).
Obciążenie procesora (ten pasek) zostanie zmieniony w przyszłości (prawdopodobnie na podział rdzenie/wątki).

Jak ktoś jest chętny, zapraszam do przetestowania. Jeśli macie jakieś sugestie, znajdziecie błąd - proszę o info.
Ps: Tłumaczenie nie jest zaimplementowane (program powinien być w języku angielskim, z wtrąceniami po polsku...

SysInfo.7z


edytowany 2x, ostatnio: Pepe
WL
  • Rejestracja:około 21 lat
  • Ostatnio:około 2 miesiące
  • Postów:1082
1
Pepe napisał(a):

Hey,
Jakiś czas temu pokazywałem jak program SysInfo działa (do gromadzenia informacji wykorzystuje WMI oraz wątki).

Od tego czasu udało mi się zaimplementować tworzenie raportu w formacie HTML (jeszcze chcę zrobić TXT).

Zamiast tworzyć HTML, TXT czy inne XLSX wypluj te wszystkie dane do JSON.
Potem mozesz użyć szablonów mustache żeby zrobić z tego HTML, TXT czy co tam chcesz.
No i łatwo można to sobie potem dostosować do własnych czy innych potrzeb.
Mam na myśli to, że dane to dane - a ich wizualizacja, to wizualizacja i powinno to być całkowicie rozdzielone.

Poza tym, możesz to zapiąć w usługę, która będzie te dane zwracała real-time np. do Grafany ;-)

Pepe
O w mordę! Nawet o takich narzędziach nie słyszałem :) Preferuję sam tworzyć warstwę wizualną, ponieważ jest dokładnie jak chcę.
WL
Wiesz w ogóle jak działa mustache? Bo ten argument z dostosowaniem do własnych potrzeb jest totalnie nietrafiony w tym kontekście. Właśnie chodzi o to, aby to łatwo można dostosować.
SK
Skoro piszemy już o mustache to tu jest implementacja dla Delphi/FPC: https://github.com/synopse/dmustache
Pepe
@wloochacz: Jak napisałem, dzisiaj się dowiedziałem, że coś takiego w ogóle istnieje. Mój projekt nie potrzebuje takich cudów. Ale, dobrze wiedzieć, że są możliwości użycia takich narzędzi.
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)