/******************************************************************************/ namespace Edit{ /******************************************************************************/ enum ERROR_TYPE { EE_ERR_NONE , EE_ERR_FILE_NOT_FOUND , EE_ERR_FILE_INVALID , EE_ERR_FILE_READ_ERROR , EE_ERR_ELM_NOT_FOUND , EE_ERR_ELM_NOT_CODE , EE_ERR_ELM_NOT_DOWNLOADED, }; #if EE_PRIVATE #define CODE_EXT "es|c|cpp|h|cs|cc|cxx|m|mm|java|txt|xml|htm|html|php|mk" /******************************************************************************/ struct LineMode // Line information, which can start with being inside comment or not (2 modes) { Bool starts_with_comment, ends_with_comment, preproc, starts_with_preproc, ends_with_preproc, starts_with_macro_param; Memc type; // type of character Memc tokens; void resetTokens() {REPAO(tokens).reset();} void clear( ) {type.clear(); tokens.clear();} TOKEN_TYPE Type (Int i)C {return InRange(i, type) ? TOKEN_TYPE(type[i]) : TOKEN_NONE;} void setTokens(Line &line); void resetType(Line &line); void setType(Line &line, Bool starts_with_comment, Bool starts_with_preproc); Bool save(File &f, StrLibrary &sl, C Str &text)C; Bool load(File &f, StrLibrary &sl, C Str &text, Line &line, Str &temp); LineMode() {starts_with_comment=ends_with_comment=preproc=starts_with_preproc=ends_with_preproc=starts_with_macro_param=false;} }; /******************************************************************************/ struct Line : Str, Text, LineMode { #if !WINDOWS typedef Text super; #endif Bool changed, text_valid, tokens_preproc_use, tokens_preproc_condition_unavailable; Int line; // original line index UID id; Source *source; LineMode comment_mode; Memc tokens_preproc; Memc& Tokens() {return tokens_preproc_use ? tokens_preproc : tokens;} C Memc& Tokens()C {return tokens_preproc_use ? tokens_preproc : tokens;} ~Line(); Line() {changed=true; text_valid=false; tokens_preproc_use=tokens_preproc_condition_unavailable=false; line=-1; id.randomize(); source=null;} void resetTokens ( ) {LineMode::resetTokens(); comment_mode.resetTokens(); REPAO(tokens_preproc).reset();} void resetPreproc(Bool inside_macro_param) {text_valid=false; starts_with_macro_param=inside_macro_param; tokens_preproc_use=inside_macro_param; tokens_preproc.clear(); REPAO(tokens).macro=false;} void preprocChanged(); void clear ( ) {Str::clear(); LineMode::clear(); comment_mode.clear(); tokens_preproc.clear(); changed=true;} void operator=(C Str &src) {clear(); Str &s=T; s=src;} Char first ()C {return Str::first();} Char last ()C {return Str::last ();} CChar* operator()()C {return Str::operator()();} Line& clip (Int length ) {Str::clip(length); changed=true; return T;} Line& clipSpaces( ) {for(; last()==' '; )removeLast(); changed=true; return T;} Line& removeLast( ) {return remove(length()-1);} Line& remove (Int i, Int num=1) { if(num>0) { Str::remove (i, num); LineMode::type.removeNum(i, num, true); comment_mode. type.removeNum(i, num, true); changed=true; } return T; } Line& insert(Int i, C Str &text, TOKEN_TYPE type=TOKEN_NONE) { if(text.is()) { Str::insert(i, text); REPAD(n, text) { LineMode::type.NewAt(i)=type; comment_mode. type.NewAt(i)=type; } changed=true; } return T; } Line& append(C Str &text, TOKEN_TYPE type=TOKEN_NONE) {return insert(length(), text, type);} Line& operator+=(Char8 c) {return append(c);} Line& operator+=(Char c) {return append(c);} Line& operator+=(CChar8 *t) {return append(t);} Line& operator+=(CChar *t) {return append(t);} Line& setChar(Int i, Char c, TOKEN_TYPE type=TOKEN_NONE) { if(InRange(i, T) && c) { Str::setChar(i, c); LineMode::type(i)=type; comment_mode. type(i)=type; changed=true; } return T; } void resetType(); void setType(Bool starts_with_comment, Bool starts_with_preproc); void setRect(Int i ); void setGui (Int i, GuiObj &parent); Int end ( ) { REPA( T)if(T[i]!=' ') return i+1; return 0;} Int start ( ) {FREPA( T)if(T[i]!=' ') return i; return 0;} Bool empty ( ) { REPA( T)if(T[i]!=' ') return false; return true;} Char chrBefore(Int x, Int *pos=null) { REP (Min(length(), x) )if(T[i]!=' '){if(pos)*pos=i; return T[i];} if(pos)*pos=-1; return 0;} Char chrNext (Int x, Int *pos=null) {for(Int i=x; i undos; Int undo_original_state; // index of UndoChange that is currently saved on the disk VecI2 suggestions_pos; Region suggestions_region; List suggestions_list; Memc suggestions; TextLine suggestions_textline; // for project elements DateTime modify_time; Bool view_comments, view_funcs, view_func_bodies, view_private_members; Memc view_lines; // Memx lines; // Memx because of Gui Text inside which requires const_mem_addr Memc symbols; // symbol definitions Memc decls; // symbol forward declarations Memc tokens; WindowIO *win_io_save; // WinIO used only for saving Symbol *lit_symbol; // highlight occurences of this symbol when drawing Str lit_symbol_cpp_name; ~Source(); Source(); // io Bool save(File &f, StrLibrary &sl)C; Bool load(File &f, StrLibrary &sl, Str &temp); ERROR_TYPE load (); void reload (); ERROR_TYPE load (C SourceLoc &loc ); Bool save (C SourceLoc &loc ); Bool saveTxt(C Str &name); void save (); Bool overwrite(); // get Bool hasUnicode ()C; Bool used ()C; Bool modified ()C; Bool hasFocus (GuiObj *go)C; Bool hasMsFocus ()C {return hasFocus(Gui.ms());} Bool hasKbFocus ()C; Bool isCurVisible()C; Token* getToken (Int token_index) {return InRange(token_index, tokens) ? tokens[token_index] : null;} Char operator[] (C VecI2 &pos )C {return InRange(pos.y, lines) ? lines[pos.y] [pos.x] : 0;} TOKEN_TYPE Type (C VecI2 &pos )C {return InRange(pos.y, lines) ? lines[pos.y].Type(pos.x) : TOKEN_NONE;} Bool lineValid (C VecI2 &pos )C {return InRange(pos.y, lines);} Bool posValid (C VecI2 &pos )C {return InRange(pos.y, lines) && InRange(pos.x, lines[pos.y]);} Vec2 posVisual (C VecI2 &pos )C; Bool insideRSTBrackets(C VecI2 &pos ) ; // if inside Round() Square[] Template<> Brackets Vec2 posCur (C Vec2 &pos )C; // convert screen position to cursor Vec2 offset ( )C; // get offset applied to code text Int findLine (C UID &id )C {REPA(lines)if(lines[i].id==id)return i; return -1;} Bool viewToReal(C VecI2 &view, VecI2 &real)C; // conversion is precise Int viewToReal( Int view )C; // conversion is precise Int realToView( Int real)C; // conversion is approximate VecI2 realToView( C VecI2 &real)C; // conversion is approximate Str textTokens()C; // operations void replacePath(C Str &src, C Str &dest); void setScroll(); void setHideSlideBar(); void curSel(VecI2 &min, VecI2 &max); VecI2& dec(VecI2 &p); VecI2& inc(VecI2 &p); // edit void startSel(); void highlight(Int line, Bool immediate); void makeCurVisible(Bool center=false, Bool immediate=true); void curLeft (); void curRight (); void curUp (); void curDown (); void curLineBegin(); void curLineEnd (); void selAll (); void selWord (); void curPrevWord(); void curNextWord(); void curPrevBracket(); void curNextBracket(); void curPrevLevelBracket(); void curNextLevelBracket(); void curPageUp (); void curPageDown(); Int viewBeginPos(); Int viewEndPos (); void curViewBegin(); void curViewEnd (); void curDocBegin(); void curDocEnd (); void curClip(); void removeLine(Int i); void delSel(Bool set_undo=true, Bool clear_suggestions=true); void cut (); void copy (); void paste (C Str *text=null, Bool move_cur=true); void separator(); void delForward(); void delBack(); void delWordForward(); void delWordBack (); void makeCase(Bool upper); void forceCreateNextUndo(); void delUndo(); void setUndo(UNDO_TYPE undo_type=DEFAULT); void undoAsChange(); void undo(); void redo(); Str asText()C; void fromText(C Str &data); // preprocessor /*Memc& macrosForLine(Int y) { for(y--; InRange(y, lines); y--)if(lines[y].has_macros)return lines[y].macros; // find first previous line which has macro definitions return ProjectMacros; // if not found then use global macros }*/ Token* previewNextToken(Int line_index, Int line_token_index); Token* getNextToken(Int &line_index, Int &line_token_index, Bool only_cur_line=false); struct TokenSource { Memc *tokens; Int token_index; // index in 'tokens' Source *source; Int *line_index, *line_token_index; // index in 'Line.tokens' Token* previewNext (); Token* next (Bool only_cur_line=false); void removeLastRead(); TokenSource() {tokens=null; token_index=0; source=null; line_index=null; line_token_index=null;} }; Int findMacro (Memc ¯os, BStr ¯o, Mems *macro_used=null); Int findMacroToReplace(Memc ¯os, BStr ¯o, TokenSource &ts, Mems *macro_used=null); Int findMacroToReplace(Memc ¯os, BStr ¯o, Int line_index, Int line_token_index); struct MacroParam { Memc tokens; }; void replaceMacro(Int macro_index, Memc ¯os, TokenSource &ts, Mems ¯o_used, Int depth, Int col, Line &line); Bool getConditionalValue(Memc &tokens, Memc ¯os, Line &line); void preprocess(Memc ¯os, Int &line_index, Memc &temp, Bool allow_defines, Memc &prep_if); // check for special preprocessor tokens (#define, #undef, #if, #ifdef, #ifndef, #else, #elif, #endif) void detectDefines(); void preprocess(Int from=0, Int num=-1); // void setTokenPtrs(); // set continuous tokens for the whole file void changed (Int from, Int num=1); void exist (Int x, Int y); Token* findPrevToken(C VecI2 &pos, Int &i); Token* findToken (C VecI2 &pos, Int &i); // expression Bool evaluateSymbol(Int start, Expr &out, Int final=-1, Bool allow_func_lists=false); // returns true if 'out' expression was returned Symbol* finalSymbol(Int final, Bool allow_func_lists=false); // suggestions void clearSuggestions (); void listSuggestions (Int force=0); // -2=project element, -1=false, 0=autodetect, 1=true void refreshSuggestions (); void suggestionsSetRect(); void setSuggestion (Int x); void autoComplete (Bool auto_space=true, Bool set_undo=true, Bool auto_brace=true, Bool call_changed=true, Bool ignore_params=false); // detect Bool getSymbolMacroID (C VecI2 &cur, SymbolPtr &symbol_ptr, Macro* ¯o_ptr, UID &id, VecI2 *x_range=null, Bool prefer_definition=false); void jumpToCur (); void findAllReferences(); // gui void visible (Bool visible) {visibleActivate(visible);} Bool visible ( ) {return super::visible();} void setOffset (); void setRegionSize (); void resize (); void themeChanged (); void setGui (); void prepareForDraw(); void validateView (); void setView (Bool comments, Bool funcs, Bool func_bodies, Bool private_members); virtual GuiObj& hide ( ) {clearSuggestions(); return super::hide();} virtual GuiObj* test (C GuiPC &gpc, C Vec2 &pos, GuiObj* &mouse_wheel); virtual void update(C GuiPC &gpc); // draw void drawSelection(C Color &color, Int y, Int min_x, Int max_x); void drawSelection(C Color &color, C VecI2 &a, C VecI2 &b, Bool including=false); virtual void draw (C GuiPC &gpc); // parse Symbol* getFullSymbol(Int &i, Str &temp, Symbol *set_parent, Memc &templates, Symbol* *symbol_parent=null, Int *symbol_index=null) {return GetFullSymbol(tokens, i, temp, set_parent, templates, symbol_parent, symbol_index);} Symbol* createSpace(Symbol &parent, Int token_index) {return symbols.New().require(parent.full_name+SEP+NamelessName(&parent)).set(&parent, Symbol::SPACE, token_index, parent.source)();} void delSymbols(); void resetSymbols() {if(!header)delSymbols();} void detectDataTypes(SymbolPtr parent=null) {if(active)DetectDataTypes(symbols, decls, tokens, parent);} void linkDataTypes( ) {if(active) LinkDataTypes(symbols, tokens );} void detectVarFuncs( ) {if(active) DetectVarFuncs(symbols, tokens );} Bool isDeclaration(Symbol *symbol, Int i) {return IsDeclaration(tokens, symbol, i);} void parseFunc (Symbol &func, Memc &cmds, Memc &msgs); // parse specified 'func' function and setup 'cmds' and 'msgs' void parseFunc (Symbol &func ); // parse specified 'func' function void parseFunc (Token &token); // parse function at 'token' token void parseFunc (C VecI2 &cur ); // parse function at 'cur' cursor position void parseCurFunc( ); // parse function at cursor position // C++ void srcTokenRange( Int t_start, Int t_end, VecI2 &start, VecI2 &end); Bool destTokenRange(Memc &clines, Int t_start, Int t_end, VecI2 &start, VecI2 &end); Str getText(Int start, Int end); void writeAll( Str &out , C VecI2 &start, C VecI2 &end); void write( Str &out , C VecI2 &start, C VecI2 &end); void write(Memc &clines, C VecI2 &start, C VecI2 &end, VecI2 *clines_start=null, Int *line_i=null); void write(Memc &clines, Int start, Int end, VecI2 *clines_start=null, Int *line_i=null); void writeTokens(CodeLine &cline, Int start, Int end, Bool gcc); void writeSymbolDecl(Memc &clines, Symbol &symbol, Bool gcc); void remove (Memc &clines, Int start, Int end, Bool definite); void removeDefVal(Memc &clines, Symbol &symbol); Int getSymbolStart(Int i); Int getListEnd (Int i); Int getBodyStart (Int i); Int getBodyEnd (Int i); Bool isFirstVar(Symbol &symbol); CChar8* adjustDot ( Int i ); // replace '.' with "->" or "::", returns string only if change is needed void adjustToken(Memc &code_lines, Int i, Bool gcc); // adjust token from Esenthel Script to C++, 'gcc'=if should be compatible with GCC void writeClassPath(CodeLine &line, Int col, Symbol *parent, Symbol *cur_namespace, Bool global, Memc *templates=null, bool start_separator=true); void expandName ( CodeLine &line, Int col, Symbol &symbol, Symbol *parent, Symbol *cur_namespace); void expandName (Memc &code_lines, Symbol &symbol, Symbol *cur_namespace); void expandRetVal (Memc &code_lines, Symbol &symbol); Bool expandableTypename( Symbol &symbol); Bool expandableTemplate(Int token_index); void expandTypename (Memc &code_lines, Symbol &symbol, Int start_line=0); void expandTemplate (Memc &code_lines, Int token_index, Int start_line=0); void expandTemplates (Memc &code_lines); void writeClassTemplates(Memc &clines, Symbol *Class); void writeCtorInit (Memc &clines, Symbol &ci , Int &line_i, Bool first, Bool gcc); void writeCtorInits (Memc &clines, Symbol &func , Int body_start, Bool gcc); void writeForcedCtor (Memc &clines, Symbol &Class, Symbol* &Namespace, Bool gcc); void detectDefaultCtors(); Bool writeClass (Memc &clines, Symbol &symbol, Bool gcc); Bool writeVarFuncs (Memc &clines, Bool gcc); Bool writeInline (Memc &clines, Bool gcc); Bool writeFunc (Memc &clines, Bool gcc, Symbol &symbol, Symbol* &Namespace); Bool writeStaticVars(Memc &clines, Bool gcc, Symbol* &Namespace, Bool templates); void makeCPP(C Str &path, C Str &file, Bool gcc, Bool include_headers); }; #endif /******************************************************************************/ } // namespace /******************************************************************************/