[#1] Jak napisać prosty edytor programisty?
Chciałbym napisać prosty edytor programisty z podświetlaniem słów kluczowych i narzędziami pomocniczymi jak lista struktur, zmiennych, klas i procedur itp.. Dla OS3.x i OS4.0. Głównym problemem jest dla mnie struktura danych dotycząca edytowanego tekstu. Optuję za listą linii.

Lista linii może mieć taki wygląd:

#define LINE_LEN 70

struct line
{
UBYTE text[LINE_LEN];
struct line *next;
};

Dzięki temu łatwo można modyfikować tekst a to jest przecież główne zadanie edytora tekstu.
Jakie są Wasze opinie na ten temat? Dziękuję za odpowiedź.

[#2] Re: Jak napisać prosty edytor programisty?

@Minniat, post #1

Minniat napisał(a):

> #define LINE_LEN 70

1a: #define to zle rozwiazanie
1b: stala maksymalna dlugosc linii to zlo. Jak bedziesz mial bardzo duzo krotkich linii to paskudnie zmarnujesz pamiec. Jak bedziesz mial dlugie linie to nie zmieszcza sie w buforze

> struct line
> {
> UBYTE text[LINE_LEN];
> struct line *next;
> };

2a. Czy zawartosc linii chcesz trzymac bezposrednio w strukturze? Czy wskaznik na bufor linii nie bylby lepszy?

2b. lista lacazona jednostronnie to bardzo prymitywna struktura danych. Mozesz sie po niej poruszac tylko w jednym kierunku. Innymi slowy, przechodzac z linii 10000 do lini 10001 odczytujesz tylko wskaznik "next", ale przechodzac z linii 10000 do lini 9999 musialbys przejsc cala liste od poczatku. Pomysl chociazby o liscie dwustronnej.

2c. AmigaOS dostarcza gotowe struktury danych:
struct List, struct MinList, struct Node, struct MinNode oraz caly zestaw funkcji i makr do operowania na nich.



Ostatnia modyfikacja: 26.08.2008 18:58:19
[#3] Re: Jak napisać prosty edytor programisty?

@Minniat, post #1

Istniejące edytory nie działają? W CubicIDE/GoldED/MorphED można sobie nawet dorobić zasady dla dowolnego (nawet nieistniejącego) języka. Jest sens to robić? Myślę, że na Aminecie pewnie jest też coś darmowego.

[#4] Re: Jak napisać prosty edytor programisty?

@MDW, post #3

MDW napisał(a):

> Jest sens to robić?

W ramach wprawki programistycznej :)

[#5] Re: Jak napisać prosty edytor programisty?

@szuler, post #2

1) W takim razie rozwiązaniem byłby bufor o zmiennej wielkości, ale wymagałoby to ciągłej realokacji pamięci dla niego,np.

struct line
{
UBYTE *text;
struct line *next;
};

text = AllocMem(line_len, MEMF_CLEAR);

2) Lista dwustronna to rzeczywiście dobre rozwiązanie.
Jeśli chodzi o systemowe listy to mógłbym zastosować je np. tak:

struct line
{
struct Node line_node;
UBYTE text[LINE_LEN];
};

Mam w tej materii duże doświadczenie (edytor poziomów do Benefactora - stosuję listy obiektów, merry-menów, węzłów trasy, zdarzeń itd.)

Teraz pora obmyśleć nad procedurami i funkcjami (lub metodami) operującymi na tej klasie danych (lista linii).

[#6] Re: Jak napisać prosty edytor programisty?

@MDW, post #3

Mam GoldED i jestem zadowolony. Ale on jest tylko dla OS3.x.
CubicIDE czy NoWinEd jeszcze nie wypróbowałem. (CubicIDE to chyba produkt komercyjny). Wprawka to jedno, drugie to chciałbym zastosować rozwiązania, które mi samemu będą służyły (np. podświetlanie słów kluczowych itd.)

[#7] Re: Jak napisać prosty edytor programisty?

@Minniat, post #5

Minniat napisał(a):

> 1) W takim razie rozwiązaniem byłby bufor o zmiennej wielkości,
> ale wymagałoby to ciągłej realokacji pamięci dla niego,np.

nie do konca... Zainteresuj sie np. czyms takim jak "piece table".

http://www.cs.unm.edu/~crowley/papers/sds/node15.html
oraz
http://www.catch22.net/tuts/zips/crowley.zip

> text = AllocMem(line_len, MEMF_CLEAR);

Nie rezerwuj pamieci w swoich programach w ten sposob. Tym bardziej jesli planujesz tysiace alokacji w swoim programie.

CreatePool/DeletePool/AllocPooled/FreePooled/AllocVecPooled/FreeVecPooled.



Ostatnia modyfikacja: 27.08.2008 08:13:10
[#8] Re: Jak napisać prosty edytor programisty?

@szuler, post #7

CreatePool/DeletePool/AllocPooled/FreePooled/AllocVecPooled/FreeVecPooled.

Poczytam o tym w dokumentacji.

[#9] Re: Jak napisać prosty edytor programisty?

@Minniat, post #8

Trzeba tylko dodać odpowiednie metody do klasy line:

void line :: Delete()
void line :: Backspace()
void line :: AddChar(char c)
void line :: SplitLine()

Delete() - kasuje literę w miejscu kursora
Backspace() - kasuje literę przed kursorem lub łączy dwie linie w całość
AddChar() - dodaje literę w miejscu kursora
SplitLine() - dzieli linię na dwie w miejscu kursora

SplitLine() jest wywoływane gdy użytkownik naciśnie RETURN

i w zasadzie edytor tekstu gotowy... :)



Ostatnia modyfikacja: 27.08.2008 12:33:02
[#10] Re: Jak napisać prosty edytor programisty?

@Minniat, post #9

Wreszcie działa atrybut CODE. (mam nadzieję, że nie doda
co linijkę) Oto przykładowa implementacja metod klasy "line" wraz z debuggingiem i komentarzami. Używam standardowych procedur stdlib i string oraz strukturę Node. Metoda "Print" jest dla testowania.
class line
{
private:
   struct Node line_node; // węzeł
   char *text; // tekst w linijce
   int linelen; // długość tekstu
   int lineused; // ilość używanych znaków

public:
   line(int len); // konstruktor pobiera długość linijki i alokuje pamięć
   ~line(); // destruktor zwalnia pamięć
   void ClearLine(); // kasuje linię
   void SetText(char *newtext); // wstawia tekst do linii
   void Print(); // wyświetla tekst
   void Backspace(); // usuwa znak przed kursorem
   void Delete(); // usuwa znak w miejscu kursora
   void AddChar(char c); // dodaje nowy znak w miejscu kursora
   void SplitLine(); // dzieli linię na dwie (póki co brak implementacji)
}
*cursorline;

int cursorpos; // pozycja x kursora

line :: line(int len)
{
   printf("Constructing line (len=%d)...n",len);
   text = (char *)malloc(len);
   linelen = len;
}

line :: ~line()
{
   printf("Deconstructing line...n" );
   free(text);
}

void line :: ClearLine()
{
   int i;

   printf("Clearing line...n" );
   text[0] = 'n';
   text[1] = '';
   for (i = 2; i < linelen; i++)
      text[ i ] = ' ';
   lineused = strlen(text);
}

void line :: SetText(char *newtext)
{
   printf("Setting text to %s", newtext );
   strcpy(text, newtext);
   lineused = strlen(text);
}

void line :: Print()
{
   printf("Printing line...n" );
   printf("CHARS: %d LINE: %s", lineused, text);
}

void line :: Backspace()
{
   int i;

   printf("Backspacing...n" );
   if (cursorpos > 0)
   {
      cursorpos--;
      for (i = cursorpos; i < lineused; i++)
         text[ i ] = text[i + 1];
      text[ i ] = '';
   }
   lineused--;
   cursorpos--;
}

void line :: Delete()
{
   int i;

   printf("Deleting...n" );
   for (i = cursorpos; i < lineused; i++)
      text[ i ] = text[i + 1];
   text[ i ] = '';
   lineused--;
}

void line::AddChar(char c)
{
   int i;

   printf("Adding char -%c-...n", c);
   lineused++;
   for (i = lineused; i > cursorpos; i--)
      text[ i ] = text[i - 1];
   text[cursorpos] = c;
   cursorpos++;
}

void line::SplitLine()
{
}
A oto przykład wykorzystania tej klasy. Trzeba dodać niezbędne inkludy. Program kompiluje się bez problemów w GCC.
int main()
{
   line testline(100);
   char test[]="Hello!n";
   cursorline = &testline;
   testline.ClearLine();
   testline.Print();
   testline.SetText(test);
   testline.Print();
   cursorpos = 5;
   printf("Setting cursor at %d...n", cursorpos);
   testline.AddChar(' ');
   testline.AddChar('W');
   testline.AddChar('o');
   testline.AddChar('r');
   testline.AddChar('l');
   testline.AddChar('d');
   testline.Print();
   return 0;
}

Jakieś komentarze i wskazówki? Klasa line pozwala na stworzenie prostego edytora wystarczy dodać ruch kursorem oraz napisać procedury piszące tekst w okienku. Następnie można go dowolnie rozbudowywać.

[#11] Re: Jak napisać prosty edytor programisty?

@Minniat, post #10

i ty uwazasz siebie za dobrego programiste....

[#12] Re: Jak napisać prosty edytor programisty?

@Minniat, post #10

line new_line(2); new_line.SetText("Dupa zbita");



Konstruktor z parametrem to zły pomysł, zrób konstruktor bezparametrowy i jak już musisz to dodaj metodę do zmieniania wielkości bufora...
Stały bufor to w ogóle bardzo zły pomysł... Sprawdzaj zakresy - czy nie wychodzisz poza bufor, i czy nie trzeba w takim przypadku realokować bufora... Bez tego ten kod to po prostu generator zwiech...

Jaki jest sens w klasie line (z założenia przechowującej jedna linie tekstu) trzymać na sile znak nowej linii?

Poza tym: piszesz w c++, a używasz funkcji biblioteki standardowej c...
Korzystanie z malloc/free w c++ to też średni pomysł... W c++ od tego masz operatory new/delete...


Nie używaj zmiennych globalnych:
int cursorpos; // pozycja x kursora

cursorline = &testline; - po co Ci to jak z tego nie korzystasz? ;)

Inne sugestie:
-przeczytaj Pasje C++ i Symfonie C++ Grębosza.
-wywal ten kod i użyj po prostu std::string, bo to co napisałes to taka... odrobinę prymitywna implementacja tej klasy.

[#13] Re: Jak napisać prosty edytor programisty?

@MinisterQ, post #12

Przede wszystkim dziękuję za komentarz, ale proszę, nie pisz tylko wad mojej implementacji metod klasy line. Poza tym to tylko zarys programu.

"Konstruktor z parametrem to zły pomysł, zrób konstruktor bezparametrowy i jak już musisz to dodaj metodę do zmieniania wielkości bufora..."
1) Jednak ten parametr jest wygodny w użyciu. Zmiana wielkości bufora jest za to odpowiednim pomysłem.

"Stały bufor to w ogóle bardzo zły pomysł... Sprawdzaj zakresy - czy nie wychodzisz poza bufor, i czy nie trzeba w takim przypadku realokować bufora... Bez tego ten kod to po prostu generator zwiech..."
2) OK. Dodam realokację bufora. Póki co metoda line::SetText() nie sprawdza, czy wychodzimy poza bufor.

"Jaki jest sens w klasie line (z założenia przechowującej jedna linie tekstu) trzymać na sile znak nowej linii?"
3) Przydaje się to tylko do testu. W edytorze tego nie będzie.

"Nie używaj zmiennych globalnych:
int cursorpos; // pozycja x kursora"

4) Ależ kursor jest tylko jeden. Jego pozycja i linia, w której się znajduje może być globalne. No chyba, że stworzę klasę kursor...

"-wywal ten kod i użyj po prostu std::string, bo to co napisałes to taka... odrobinę prymitywna implementacja tej klasy."
5) Napisałem własną implementację. Poza tym dochodzi metoda JoinLine() i SplitLine(), które są potrzebne w edytorze tekstu.



Ostatnia modyfikacja: 08.09.2008 13:05:40
[#14] Re: Jak napisać prosty edytor programisty?

@Minniat, post #13

ale proszę, nie pisz tylko wad mojej implementacji metod klasy line.

Wymień proszę w takim razie jakieś zalety.

Jednak ten parametr jest wygodny w użyciu. Zmiana wielkości bufora jest za to odpowiednim pomysłem.

Niby w jaki sposób tu widać tą wygodę? Dla przykładu:
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/StringBuffer.html -> wyobrażasz sobie wygodę użycia tej klasy w przypadku gdyby dysponowała jedynie konstruktorem sztywno określającym wielkość bufora roboczego?

[#15] Re: Jak napisać prosty edytor programisty?

@MinisterQ, post #14

ClearLine(), Backspace(), Delete(), AddChar(), SplitLine(), JoinLines(), które za Chiny nie znajdziesz w klasie std::string.

[#16] Re: Jak napisać prosty edytor programisty?

@Minniat, post #15

Minniat napisał(a):

> ClearLine(),
clear ();


> Backspace(),
string& erase ( size_t pos = 0, size_t n = npos );
iterator erase ( iterator position );
iterator erase ( iterator first, iterator last );


> Delete(),
string& erase ( size_t pos = 0, size_t n = npos );
iterator erase ( iterator position );
iterator erase ( iterator first, iterator last );


> AddChar(),
string& insert ( size_t pos1, const string& str );
 string& insert ( size_t pos1, const string& str, size_t pos2, size_t n );
 string& insert ( size_t pos1, const char* s, size_t n);
 string& insert ( size_t pos1, const char* s );
 string& insert ( size_t pos1, size_t n, char c );
iterator insert ( iterator p, char c );
    void insert ( iterator p, size_t n, char c );
template
    void insert ( iterator p, InputIterator first, InputIterator last );


> SplitLine(),
string substr ( size_t pos = 0, size_t n = npos ) const;


twoja klasa nie zawiera implementacji tej metody.

> JoinLines(),
std::string string_1;
std::string string_2;
std::string string_3;

string_1 = "Hello ";
string_2 = "World";
string_3 = string_1 + string_2;

std::cout << string_3 << std::endl;


twoja klasa nie zawiera implementacji tej metody.

> które za Chiny

za Chiny to ty nie umiesz programowac.



Ostatnia modyfikacja: 08.09.2008 14:29:20



Ostatnia modyfikacja: 08.09.2008 14:29:50
[#17] Re: Jak napisać prosty edytor programisty?

@szuler, post #16

Dziękuję za opracowanie. Nie będę się z Panem spierał. Wykorzystanie klas iterator i string jest tu bogate i Pańska znajomość C++ też. Napisał pan jednak swoje implementacje moich metod. Klasa line jest zorientowana pod kątem edytora tekstu. Na przykład używa struktury Node, by połączyć linijki, więc SplitLine() będzie dodawał nowy węzeł, a JoinLines() będzie kasował jeden węzeł. Poza tym moja implementacja jest po prostu napisana tak jak chciałem i używa prostych iteracji for (np. Delete(), AddChar(), Backspace()).



Ostatnia modyfikacja: 08.09.2008 15:18:02
[#18] Re: Jak napisać prosty edytor programisty?

@szuler, post #16

umie programować tylko nie w c++

[#19] Re: Jak napisać prosty edytor programisty?

@rzookol, post #18

W C++ dopiero zaczynam, ale mam już pewną wiedzę.

[#20] Re: Jak napisać prosty edytor programisty?

@Minniat, post #10

Patrząc z punktu widzenia wzorca projektowego MVC skupiłeś się na razie na M czyli na modelu. A mówiąc w sposób zrozumiały dla wszystkich musisz to jeszcze wyświetlić . Do tego obsłużyć kursor zarówno jeśli chodzi o przemiaszczanie (w tym myszą) jak i rysowanie. Podejrzewam że czeka Cie niemiła niespodzianka gdy zaczniesz zastanawiać się nad rozwiązaniem problemu Taba. Tak czy inaczej jeśli chodzi o edytor programisty zastosowanie podejścia, w którym każda linia jest trzymana osobno (czyli takiego jak Twoje) nie jest złe. Ułatwi i przyspieszy to bardzo parsowania tekstu gdy będziesz chciał zrealizować podświetlanie. Jednak sam model (czyli to co masz) to początek początku. Czeka Cie jeszcze dużo pracy zwłaszcza jeśli chcesz to zrobić porządnie i nie wyświetlać całego tekstu co operację. Proponowałbym posłuchać Szulera i wykorzystać stl. Czas nie jest z gumy a gotowy sprawdzony kod umożliwia efektywniejsze wykorzystanie go. Dodatkowo rozdzielając operacje na jednej linii i wykorzystując do nich stringa od operacji na całym modelu (czyli te wykonywane na więcej niż jednej linii) ułatwiasz sobie pisanie testów. Nie widzę również sensu wykorzystywania list execowych, według mnie one nie są do tego, lepiej użyć kontenerów z stl. To umożliwi Ci wykorzystanie funkcji tam zawartych operujących właśnie na tych kontenerach. Odpadnie Ci dzięki temu trochę pracy.

[#21] Re: Jak napisać prosty edytor programisty?

@smith, post #20

Z wyświetleniem nie jest problem. Wykorzystam szybkie funkcje graphics.library Move(), Text() i SetAPen() oraz scrollery gadtools.library. Z obsługą kursora podobnie, zapewne zastosuję SetDrMd() i SetAPen() na jeden znak oraz obsłużę przesuw kursora poprzez IDCMP_RAWKEY oraz IDCMP_MOUSEBUTTONS. Jeśli chodzi o TAB to mogę dopisać metodę Tab(), która przesuwa tekst lub po prostu przesunąć kursor o kilka znaków. Dzięki liście linijek można w sposób szybki i łatwy dodawać nowe linijki lub kasować je oraz po prostu edytować tekst, więc ten sposób jest jednym z najlepszych do edytora tekstu! Jeśli chodzi o listy execowe to jestem do nich przyzwyczajony. W przypadku kontenerów stl to mój biedny GCC nie potrafi obsłużyć nawet i std::cout, a co dopiero przeciążone metody erase i insert lub operator dodawania. Musiałem ograniczyć się w tym przypadku do starego dobrego printf().



Ostatnia modyfikacja: 09.09.2008 09:31:39
[#22] Re: Jak napisać prosty edytor programisty?

@Minniat, post #21

sciągnij może gcc 3.x na 68k i nie marudź

Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem