Instrukcją wiążąca With a uzyskanie adresu klasy.

Instrukcją wiążąca With a uzyskanie adresu klasy.
RD
  • Rejestracja:około 12 lat
  • Ostatnio:10 miesięcy
  • Postów:212
0

Zastanawiam się jak najprościej uzyskać adres zmiennej w takim przypadku:

Kopiuj
with TJakasKlasa.Create(Application) do
begin
  ZrobTo;
  Update(Self_TJakasKlasa); 
end;

//zamiast robić tak 

v := TJakasKlasa.Create(Application);
v.ZrobTo;
Update(v);
edytowany 1x, ostatnio: flowCRANE
WL
Za używanie with powinno się palce łamać...
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około godziny
  • Lokalizacja:Tuchów
  • Postów:12165
0

Nijak – jeśli używasz with w połączeniu z konstruktorem. Nie używaj takiej konstrukcji, bo raz, że nie masz dostępu do referencji, a dwa, że ten kod jest niebezpieczny i w przypadku wyjątku spowoduje wyciek pamięci. Używanie lokalnych zmiennych nie boli, tak samo jak konstrukcji try finally do zabezpieczania przed wyciekami.


Tak z ciekawości, skoro Delphi posiada ”inline variables” – czy poniższy kod jest kompilowalny?

Kopiuj
with var Foo: TFoo := TFoo.Create() do
try
  Foo.DoThis();
  Foo.DoThat();

  DoSomething(Foo);
finally
  Foo.Free();
end;

Miałbyś fikuśne rozwiązanie swojego problemu.


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
RD
  • Rejestracja:około 12 lat
  • Ostatnio:10 miesięcy
  • Postów:212
0

Niestety mam wersję Tokyo 10.2.3 a takie deklarowanie zmiennych jest w nowszym RIO :(

zrobiłem tak:

Kopiuj
type
  TFramePlus = class(TFrame)
    FrameAdapter: TsFrameAdapter;
  private
    { Private declarations }
  public
    function GetSelf: Pointer;
    procedure AfterCreation; virtual; 
    procedure BeforeDestroy; virtual; 
  end;

function TFramePlus.GetSelf: Pointer;
begin
  Result := Self;
end;


procedure CreateTabAndOpen(APageControl: TsPageControl; AFrame: TClassOfFrame; Typ: TTypeOperation; ATabName: string);

  function NameTab: string;
  begin
    case Typ of
      Add: Result := TFramePlus(AFrame).Name+'_ADD';
      Edit: Result := TFramePlus(AFrame).Name+'_EDIT';
    end;
  end;

var
  TabSheet: TsTabSheet;
  Component: TComponent;
begin
  Component := APageControl.FindComponent(NameTab);
  If Component <> nil then
    APageControl.ActivePage := TsTabSheet(Component)
  else
  begin
    TabSheet := TsTabSheet.Create(APageControl);
    TabSheet.Name := NameTab;
    TabSheet.Caption := ATabName;
    TabSheet.UseCloseBtn := true;
    TabSheet.PageControl := APageControl;
    with AFrame.Create(Application) do
    begin
      FormData.SkinManager.UpdateScale(GetSelf);
      Parent := TabSheet;
      APageControl.ActivePage := TabSheet;
    end;
  end;
end;

Funkcją GetSelf pobieram referencję

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

No dobra, jakieś to rozwiązanie jest, ale po co na siłę używasz with, skoro w tym przypadku potrzebujesz referencji? Utwórz tę ramkę w sposób standardowy, z wykorzystaniem zmiennej lokalnej – w niczym to nie przeszkodzi.


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
RD
  • Rejestracja:około 12 lat
  • Ostatnio:10 miesięcy
  • Postów:212
0

Czyli takie rozwiązanie jest lepsze i pewniejsze wraz z użyciem try except?

Kopiuj
begin
  Component := APageControl.FindComponent(NameTab);
  If Component <> nil then
    APageControl.ActivePage := TsTabSheet(Component)
  else
  begin
    TabSheet := TsTabSheet.Create(APageControl);
    try
      TabSheet.Name := NameTab;
      TabSheet.Caption := ATabName;
      TabSheet.UseCloseBtn := true;
      TabSheet.PageControl := APageControl;
      Frame := AFrame.Create(Application);
      try
        FormData.SkinManager.UpdateScale(Frame);
        Frame.Id := Id;
        Frame.Parent := TabSheet;
        APageControl.ActivePage := TabSheet;
      except
        Frame.Free;
        raise;
      end;
    except
      TabSheet.Free;
      raise;
    end;
  end;
end;
GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 2 godziny
0

Czyli takie rozwiązanie jest lepsze i pewniejsze wraz z użyciem try except?

Nie do końca. Blok try except end służy do obsługi wyjątków a samo zwalnianie obiektu należy umieścić w bloku try finally end. Możesz je zagnieździć

Kopiuj
try
    MyClass := TMYclass.Create(Self);
    try
      .....
    finally
       MyClass.Free;
    end;
except
    // obsługa wyjątku.
end;

można zastosować odwrotne zagnieżdżenie

Kopiuj
try
    MyClass := TMYclass.Create(Self);
    try
      .....
    except
      // obsługa wyjątku
    end;
finally
     MyClass.Free;
end;

Stosowałem takie rozwiązanie w sytuacji kiedy obsługa wyjątku wymagała dostępu do obiektu generującego wyjątek .
Ale wtedy ryzykujemy że obsługa wyjątku w sekcji except może generować kolejny wyjątek .

Wtedy można zrobić podwójne zagnieżdżenie

Kopiuj
try 
  try
    MyClass := TMYclass.Create(Self);
    try
      .....
    except
      // obsługa pierwotnego wyjątku
    end;
  finally
     MyClass.Free;   
  end;
except
  // obsługa ewentualnego wyjątku  powstałego w obsłudze pierwotnego wyjątku 
end;

Taki wariant po pierwsze zapewnia możliwość dostępu do obiektu generującego wyjątek na etapie obsługi pierwotnego wyjątku, a po drugie zapewnia że cała sekcja jest zamknięta, czyli zwalnia obiekt i obsłuży wszystkie wyjątki bez względu na na miejsce ich powstania/

edytowany 2x, ostatnio: grzegorz_so
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około godziny
  • Lokalizacja:Tuchów
  • Postów:12165
0

Zwalnianie komponentu – nawet w przypadku wyjątku – nie jest konieczne, bo tym zajmie się komponent będący jego rodzicem. Tak więc spokojnie można usunąć z kodu wywołania Free, tak samo jak oba bloki try except.


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.
GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 2 godziny
0

Zwalnianie komponentu – nawet w przypadku wyjątku – nie jest konieczne, bo tym zajmie się komponent będący jego rodzicem. Tak więc spokojnie można usunąć z kodu wywołania Free, tak samo jak oba bloki >try except.

W pierwszym punkcie masz rację, ale to był szkolny przykład, nie każdy obiekt musi mieć rodzica. Parentem może być nil albo konstruktor klasy nie ma "parenta".
A w drugim,to nie rozumiem dlaczego uważasz że można usunąć bloki try except

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

W pierwszym punkcie masz rację, ale to był szkolny przykład, nie każdy obiekt musi mieć rodzica. Parentem może być nil albo konstruktor klasy nie ma "parenta".

Tak, ale mój post jest odpowiedzią na post OP, a nie na Twój. ;)

A uściślając – nie rodzicem, a właścicielem, bo chodzi o parametr Owner konstruktora, a nie o właściwość Parent. Przy czym w kodzie podanym przez OP, są tworzone komponenty wizualne, zawsze posiadające zarówno właściciela, jak i rodzica (używane jest albo Application, albo APageControl).

A w drugim,to nie rozumiem dlaczego uważasz że można usunąć bloki try except

Bo są zbędne – jeśli komponent zostanie prawidłowo stworzony, to jego zwolnieniem zajmie się właściciel. A jeśli nie, to konstruktor zadba o dealokację komponentu niepoprawnie utworzonego, a kolejne instrukcje (i kolejne wywołania konstruktorów) zostaną pominięte, więc nie będzie czego sprzątać.

Tym bardziej że jedyne co się znajduje wewnąrz except to nadmiarowy Free oraz raise, który puszcza wyjątek dalej. Dokładnie to samo można osiągnąć usuwając te bloki – działanie się nie zmieni, a kodu będzie mniej.


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
RD
  • Rejestracja:około 12 lat
  • Ostatnio:10 miesięcy
  • Postów:212
0

Dziękuję wszystkim za podpowiedzi. Wracając do tematu kod musi być z try.. except jak poniżej:

Kopiuj
begin
  Component := APageControl.FindComponent(NameTab);
  If Component <> nil then
    APageControl.ActivePage := TsTabSheet(Component)
  else
  begin
    TabSheet := TsTabSheet.Create(APageControl);
    try
      TabSheet.Name := NameTab;
      TabSheet.Caption := ATabName;
      TabSheet.UseCloseBtn := true;
      TabSheet.PageControl := APageControl;
      Frame := AFrame.Create(TabSheet);
      FormData.SkinManager.UpdateScale(Frame);
      Frame.Id := Id;
      Frame.Parent := TabSheet;
      APageControl.ActivePage := TabSheet;
    except
      APageControl.Pages[TabSheet.PageIndex].Free;
      raise;
    end;
  end;
end;

Ponieważ @furious programming ma rację można wywalić zwalniania obiektów bo tym zajmą się wskazane komponenty podczas tworzenia Frame i Tabsheet. Ale i to ale jest najważniejsze. W sytuacji gdy np Frame wygeneruje wyjątek. To TabSheet i Frame jest już stworzone i zwolnione by została dopiero po zwolnieniu APageControl czyli w moim przypadku po zamknięciu aplikacji. Co jest bezsensu dla mnie. Dlatego muszę użyć sekcję try .. except z Free bo inaczej otrzymam błąd przy kolejnej próbie wykonania procedury ( taka nazwa komponentu już istnieje - a dokładnie zobaczę pustą stronę TabSheet ).

Jedynie Frame.Free mogę pominąć bo tym zajmie się Tabsheet po wywołaniu tabsheet.free.

RD
  • Rejestracja:około 12 lat
  • Ostatnio:10 miesięcy
  • Postów:212
0

Niechcąc zakładać kolejnego posta powiąże go z tym. Powyżej przedstawiłem dynamiczne tworzenie zakładki i ramki. I teraz na tej ramce mam przycisk z poniższym kodem:

Kopiuj
procedure Button;
begin
  if Parent.ClassName = 'TsTabSheet' then
    TsPageControl(Parent.Parent).Pages[TsTabSheet(Parent).PageIndex].Free;
end;

Która ma za zadanie zamknąć zakładkę TabSheet wraz z ramką. I to prawie działa bo zamyka ale po drodze otrzymuję błędy AV. No tak sobie myślę że chce zniszczyć Frame które jeszcze wykonuje kod w Button. Jakie jest najlepsze rozwiązanie takiej sytuacji?

  • Wysłać komunikat do formy głównej która zniszczy zakładkę po np 100 ms?
KA
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Gorlice
0

Kombinujesz taki kod powinien działać:

Kopiuj
procedure TFrame1.Button1Click(Sender: TObject);
begin
  Self.Parent.Free;
end;

Rodzicem Frame jest TabSheet, który zadba o zwolnienie Frame.


Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około godziny
  • Lokalizacja:Tuchów
  • Postów:12165
0

@kAzek: na pewno powinno działać? Żaden obiekt nie może sam siebie zwolnić z poziomu swojej metody, a do tego się sprowadza to co pokazałeś. IMO trzeba by ”asynca” użyć, aby to było możliwe.

Pod Lazarusem skorzystałbym z QueueAsyncCall, a w Delphi nie wiem co tam macie.


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
KA
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Gorlice
0

Działa i nie sam siebie zwalnia tylko rodzica a rodzic dopiero komponenty. Jest tak zwalnia TabSheet który zwalnia Frame a dopiero Frame zwalnia ten Button, który to wywołał (i inne komponenty).

EDIT: @furious programming
Proste sprawdzenie kod tworzenia TabSheet i Frame:

Kopiuj
procedure TForm4.Button1Click(Sender: TObject);
var
  TabSheet: TTabSheet;
  Frame: TFrame1;
  Name: string;
  i: Integer;
begin
  TabSheet:= TTabSheet.Create(PageControl1);
  try
    i:= 0;
    repeat
      Inc(i);
      Name:= 'TabSheet' + IntToStr(i);
    until (PageControl1.FindChildControl(Name) = nil);
    TabSheet.Name:= Name;
    TabSheet.Caption:= Name;
    Frame:= TFrame1.Create(nil); //specjalnie bez własciciela
    Frame.Parent:= TabSheet;
    TabSheet.PageControl:= TPageControl(TabSheet.Owner);
    //raise Exception.Create('Error');
  except
    on E: Exception do begin
      TabSheet.Free;
      ShowMessage(E.Message);
    end
  end;
end;

Button na Frame zwalniający w wersji wszystko ok:

Kopiuj
procedure TFrame1.Button1Click(Sender: TObject);
begin
  Self.Parent.Free;
end;

w wersji z wyciekiem pamięci

Kopiuj
procedure TFrame1.Button1Click(Sender: TObject);
var
  oldParent: TWinControl;
begin
  oldParent:= Self.Parent;
  Self.Parent:= nil; //pozbywamy się rodzica. Nie ma rodzica ani właściciela więc zwolnienie TabSheet nie zwolni Frame
  oldParent.Free; //zwalniamy TabSheet
end;

Gdyby kod Self.Parent.Free działał źle to albo by się wykrzaczał albo powodował wyciek a nic takiego nie ma miejsca.


Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
edytowany 2x, ostatnio: kAzek
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około godziny
  • Lokalizacja:Tuchów
  • Postów:12165
0
kAzek napisał(a):

Działa i nie sam siebie zwalnia tylko rodzica a rodzic dopiero komponenty. Jest tak zwalnia TabSheet który zwalnia Frame a dopiero Frame zwalnia ten Button, który to wywołał (i inne komponenty).

No właśnie, czyli de facto sam siebie zwalnia, tyle że pośrednio – wszystkie kontrolki zostaną zwolnione (łącznie z przyciskiem wywołującym) zanim zdarzenie OnClick zakończy swoje działanie. No ale skoro działa i nie leci wyjątek to widać implementacja pozwala na taki zabieg (jest to dozwolone).

Napisałeś, że „powinno działać”, jakbyś nie był pewny – dlatego dopytałem, bo sam też nie byłem pewny czy to zadziała.


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
RD
  • Rejestracja:około 12 lat
  • Ostatnio:10 miesięcy
  • Postów:212
0
kAzek napisał(a):

Kombinujesz taki kod powinien działać:

Kopiuj
procedure TFrame1.Button1Click(Sender: TObject);
begin
  Self.Parent.Free;
end;

Rodzicem Frame jest TabSheet, który zadba o zwolnienie Frame.

Niestety ten kod jest nie poprawny. Owszem zamyka zakładkę ale gdy w pagecontrol próbujemy myszką przejść na inną zakładkę otrzymujemy błąd 'Invalid pointer' czego nie ma gdy użyjemy tej mojej zawiłej instrukcji:

Kopiuj
TsPageControl(Parent.Parent).Pages[TsTabSheet(Parent).PageIndex].Free;

A sam błąd wywalał komonent z AlphaSkins - już zostało zlokalizowane i naprawione.

flowCRANE
AlphaSkins – nieźle. Jak wrażenia z używania?
RD
@furious programming: Używam ich od wersji chyba 8 czy 9. I obecnie są naprawdę dobre. Wersja 14 jest stabilna a 15 ma sporo błędów ale ruski szybko działają jest dobry kontakt. Można im wysłać własny kod do danego komponentu który chcemy i go dodają w następnych wersjach. Nawet kilka miesięcy temu zastanawiałem się czy nie przejść na coś innego i nic nie znalazłem co by dorównało AC.
RD
@furious programming: Najciekawsze jest iż można zmieniać rozdzielczość aplikacji nawet co 1%. I działa dla komponentów z poza Alpha skins.
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)