diff --git a/data/filetypes.tcl b/data/filetypes.tcl new file mode 100644 index 00000000..13a7fbe6 --- /dev/null +++ b/data/filetypes.tcl @@ -0,0 +1,54 @@ +# For complete documentation of this file; please see Geany's main documentation +[styling] +# foreground;background;bold;italic +default=0x000000;0xffffff;false;false +comment=0x0000ff;0xffffff;false;false +commentline=0x0000ff;0xffffff;false;false +number=0x007f00;0xffffff;false;false +operator=0x101030;0xffffff;false;false +identifier=0x0000a2;0xffffff;false;false +wordinquote=0x7f007f;0xffffff;false;false +inquote=0x7f007f;0xffffff;false;false +substitution=0x991111;0xffffff;false;false +modifier=0x7f007f;0xffffff;false;false +expand=0x100000;0xffffff;false;false +wordtcl=0x991111;0xffffff;true;false +wordtk=0x00007f;0xffffff;true;false +worditcl=0x991111;0xffffff;true;false +wordtkcmds=0x00007f;0xffffff;true;false +wordexpand=0x00007f;0xffffff;true;false + + +[keywords] +# all items must be in one line +tcl=after append array auto_execok auto_import auto_load auto_load_index auto_qualify beep bgerror binary break case catch cd clock close concat continue dde default echo else elseif encoding eof error eval exec exit expr fblocked fconfigure fcopy file fileevent flush for foreach format gets glob global history http if incr info interp join lappend lindex linsert list llength load loadTk lrange lreplace lsearch lset lsort memory msgcat namespace open package pid pkg::create pkg_mkIndex Platform-specific proc puts pwd re_syntax read regexp registry regsub rename resource return scan seek set socket source split string subst switch tclLog tclMacPkgSearch tclPkgSetup tclPkgUnknown tell time trace unknown unset update uplevel upvar variable vwait while +tk=bell bind bindtags bitmap button canvas checkbutton clipboard colors console cursors destroy entry event focus font frame grab grid image Inter-client keysyms label labelframe listbox lower menu menubutton message option options pack panedwindow photo place radiobutton raise scale scrollbar selection send spinbox text tk tk_chooseColor tk_chooseDirectory tk_dialog tk_focusNext tk_getOpenFile tk_messageBox tk_optionMenu tk_popup tk_setPalette tkerror tkvars tkwait toplevel winfo wish wm +itcl=@scope body class code common component configbody constructor define destructor hull import inherit itcl itk itk_component itk_initialize itk_interior itk_option iwidgets keep method private protected public +tkcommands=tk_bisque tk_chooseColor tk_dialog tk_focusFollowsMouse tk_focusNext tk_focusPrev tk_getOpenFile tk_getSaveFile tk_messageBox tk_optionMenu tk_popup tk_setPalette tk_textCopy tk_textCut tk_textPaste tkButtonAutoInvoke tkButtonDown tkButtonEnter tkButtonInvoke tkButtonLeave tkButtonUp tkCancelRepeat tkCheckRadioDown tkCheckRadioEnter tkCheckRadioInvoke tkColorDialog tkColorDialog_BuildDialog tkColorDialog_CancelCmd tkColorDialog_Config tkColorDialog_CreateSelector tkColorDialog_DrawColorScale tkColorDialog_EnterColorBar tkColorDialog_HandleRGBEntry tkColorDialog_HandleSelEntry tkColorDialog_InitValues tkColorDialog_LeaveColorBar tkColorDialog_MoveSelector tkColorDialog_OkCmd tkColorDialog_RedrawColorBars tkColorDialog_RedrawFinalColor tkColorDialog_ReleaseMouse tkColorDialog_ResizeColorBars tkColorDialog_RgbToX tkColorDialog_SetRGBValue tkColorDialog_StartMove tkColorDialog_XToRgb tkConsoleAbout tkConsoleBind tkConsoleExit tkConsoleHistory tkConsoleInit tkConsoleInsert tkConsoleInvoke tkConsoleOutput tkConsolePrompt tkConsoleSource tkDarken tkEntryAutoScan tkEntryBackspace tkEntryButton1 tkEntryClosestGap tkEntryGetSelection tkEntryInsert tkEntryKeySelect tkEntryMouseSelect tkEntryNextWord tkEntryPaste tkEntryPreviousWord tkEntrySeeInsert tkEntrySetCursor tkEntryTranspose tkEventMotifBindings tkFDGetFileTypes tkFirstMenu tkFocusGroup_BindIn tkFocusGroup_BindOut tkFocusGroup_Create tkFocusGroup_Destroy tkFocusGroup_In tkFocusGroup_Out tkFocusOK tkGenerateMenuSelect tkIconList tkIconList_Add tkIconList_Arrange tkIconList_AutoScan tkIconList_Btn1 tkIconList_Config tkIconList_Create tkIconList_CtrlBtn1 tkIconList_Curselection tkIconList_DeleteAll tkIconList_Double1 tkIconList_DrawSelection tkIconList_FocusIn tkIconList_FocusOut tkIconList_Get tkIconList_Goto tkIconList_Index tkIconList_Invoke tkIconList_KeyPress tkIconList_Leave1 tkIconList_LeftRight tkIconList_Motion1 tkIconList_Reset tkIconList_ReturnKey tkIconList_See tkIconList_Select tkIconList_Selection tkIconList_ShiftBtn1 tkIconList_UpDown tkListbox tkListboxAutoScan tkListboxBeginExtend tkListboxBeginSelect tkListboxBeginToggle tkListboxCancel tkListboxDataExtend tkListboxExtendUpDown tkListboxKeyAccel_Goto tkListboxKeyAccel_Key tkListboxKeyAccel_Reset tkListboxKeyAccel_Set tkListboxKeyAccel_Unset tkListboxMotion tkListboxSelectAll tkListboxUpDown tkMbButtonUp tkMbEnter tkMbLeave tkMbMotion tkMbPost tkMenuButtonDown tkMenuDownArrow tkMenuDup tkMenuEscape tkMenuFind tkMenuFindName tkMenuFirstEntry tkMenuInvoke tkMenuLeave tkMenuLeftArrow tkMenuMotion tkMenuNextEntry tkMenuNextMenu tkMenuRightArrow tkMenuUnpost tkMenuUpArrow tkMessageBox tkMotifFDialog tkMotifFDialog_ActivateDList tkMotifFDialog_ActivateFEnt tkMotifFDialog_ActivateFList tkMotifFDialog_ActivateSEnt tkMotifFDialog_BrowseDList tkMotifFDialog_BrowseFList tkMotifFDialog_BuildUI tkMotifFDialog_CancelCmd tkMotifFDialog_Config tkMotifFDialog_Create tkMotifFDialog_FileTypes tkMotifFDialog_FilterCmd tkMotifFDialog_InterpFilter tkMotifFDialog_LoadFiles tkMotifFDialog_MakeSList tkMotifFDialog_OkCmd tkMotifFDialog_SetFilter tkMotifFDialog_SetListMode tkMotifFDialog_Update tkPostOverPoint tkRecolorTree tkRestoreOldGrab tkSaveGrabInfo tkScaleActivate tkScaleButton2Down tkScaleButtonDown tkScaleControlPress tkScaleDrag tkScaleEndDrag tkScaleIncrement tkScreenChanged tkScrollButton2Down tkScrollButtonDown tkScrollButtonDrag tkScrollButtonUp tkScrollByPages tkScrollByUnits tkScrollDrag tkScrollEndDrag tkScrollSelect tkScrollStartDrag tkScrollTopBottom tkScrollToPos tkTabToWindow tkTearOffMenu tkTextAutoScan tkTextButton1 tkTextClosestGap tkTextInsert tkTextKeyExtend tkTextKeySelect tkTextNextPara tkTextNextPos tkTextNextWord tkTextPaste tkTextPrevPara tkTextPrevPos tkTextPrevWord tkTextResetAnchor tkTextScrollPages tkTextSelectTo tkTextSetCursor tkTextTranspose tkTextUpDownLine tkTraverseToMenu tkTraverseWithinMenu +expand= + + +[settings] +# the following characters are these which a "word" can contains, see documentation +wordchars=_#&abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 + +# if only single comment char is supported like # in this file, leave comment_close blank +comment_open=# +comment_close= + +# set to false if a comment character/string should start a column 0 of a line, true uses any +# indention of the line, e.g. setting to true causes the following on pressing CTRL+d + #command_example(); +# setting to false would generate this +# command_example(); +# This setting works only for single line comments +comment_use_indent=true + + +[build_settings] +# %f will be replaced by the complete filename +# %e will be replaced by the filename without extension +# (use only one of it at one time) +compiler=tclsh8.4 "%f" +run_cmd=tclsh8.4 "%f" + diff --git a/scintilla/KeyWords.cxx b/scintilla/KeyWords.cxx index 9b47ae23..353e05e3 100644 --- a/scintilla/KeyWords.cxx +++ b/scintilla/KeyWords.cxx @@ -163,6 +163,7 @@ int Scintilla_LinkLexers() { LINK_LEXER(lmPerl); LINK_LEXER(lmRuby); LINK_LEXER(lmSQL); + LINK_LEXER(lmTCL); //--Autogenerated -- end of automatically generated section diff --git a/scintilla/LexTCL.cxx b/scintilla/LexTCL.cxx new file mode 100644 index 00000000..80bf51aa --- /dev/null +++ b/scintilla/LexTCL.cxx @@ -0,0 +1,317 @@ +// Scintilla source code edit control +/** @file LexTCL.cxx + ** Lexer for TCL language. + **/ +// Copyright 1998-2001 by Andre Arpin +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "StyleContext.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +// Extended to accept accented characters +static inline bool IsAWordChar(int ch) { + return ch >= 0x80 || + (isalnum(ch) || ch == '_' || ch ==':'); // : name space separator +} + +static inline bool IsAWordStart(int ch) { + return ch >= 0x80 || + (isalpha(ch) || ch == '_'); +} + +static inline bool IsANumberChar(int ch) { + // Not exactly following number definition (several dots are seen as OK, etc.) + // but probably enough in most cases. + return (ch < 0x80) && + (isdigit(ch) || toupper(ch) == 'E' || + ch == '.' || ch == '-' || ch == '+'); +} + +static void ColouriseTCLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { + bool foldComment = styler.GetPropertyInt("fold.comment") != 0; + bool commentLevel = false; + bool subBrace = false; // substitution begin with a brace ${.....} + enum tLineState {LS_DEFAULT, LS_OPEN_COMMENT, LS_OPEN_DOUBLE_QUOTE, LS_MASK_STATE = 0xf, + LS_COMMAND_EXPECTED = 16, LS_BRACE_ONLY = 32 } lineState = LS_DEFAULT; + bool prevSlash = false; + int currentLevel = 0; + bool expected = 0; + int subParen = 0; + + int currentLine = styler.GetLine(startPos); + length += startPos - styler.LineStart(currentLine); + // make sure lines overlap + startPos = styler.LineStart(currentLine); + + WordList &keywords = *keywordlists[0]; + WordList &keywords2 = *keywordlists[1]; + WordList &keywords3 = *keywordlists[2]; + WordList &keywords4 = *keywordlists[3]; + WordList &keywords5 = *keywordlists[4]; + WordList &keywords6 = *keywordlists[5]; + WordList &keywords7 = *keywordlists[6]; + WordList &keywords8 = *keywordlists[7]; + WordList &keywords9 = *keywordlists[8]; + + if (currentLine > 0) { + int ls = styler.GetLineState(currentLine - 1); + lineState = tLineState(ls & LS_MASK_STATE); + expected = LS_COMMAND_EXPECTED == tLineState(ls & LS_COMMAND_EXPECTED); + subBrace = LS_BRACE_ONLY == tLineState(ls & LS_BRACE_ONLY); + currentLevel = styler.LevelAt(currentLine - 1) >> 17; + commentLevel = (styler.LevelAt(currentLine - 1) >> 16) & 1; + } else + styler.SetLevel(0, SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG); + bool visibleChars = false; + + int previousLevel = currentLevel; + StyleContext sc(startPos, length, initStyle, styler); + for (; ; sc.Forward()) { + bool atEnd = !sc.More(); // make sure we process last word at end of file +next: + if (subBrace) { + if (sc.ch == '}') { + subBrace = false; + sc.SetState(SCE_TCL_OPERATOR); // } + sc.ForwardSetState(SCE_TCL_DEFAULT); + } + else + sc.SetState(SCE_TCL_SUB_BRACE); + if (!sc.atLineEnd) + continue; + } else if (sc.state == SCE_TCL_DEFAULT || sc.state ==SCE_TCL_OPERATOR) { + expected &= isspacechar(static_cast(sc.ch)) || IsAWordStart(sc.ch); + } else if (sc.state == SCE_TCL_SUBSTITUTION) { + if (sc.ch == '(') + subParen++; + else if (sc.ch == ')') { + if (subParen) + subParen--; + else + sc.SetState(SCE_TCL_DEFAULT); // lets the code below fix it + } else if (!IsAWordChar(sc.ch)) { + sc.SetState(SCE_TCL_DEFAULT); + subParen = 0; + } + } + else + { + if (!IsAWordChar(sc.ch)) { + if (sc.state == SCE_TCL_IDENTIFIER || sc.state == SCE_TCL_MODIFIER || expected) { + char s[100]; + sc.GetCurrent(s, sizeof(s)); + bool quote = sc.state == SCE_TCL_IN_QUOTE; + if (commentLevel || expected) { + if (keywords.InList(s)) { + sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD); + } else if (keywords2.InList(s)) { + sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD2); + } else if (keywords3.InList(s)) { + sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD3); + } else if (keywords4.InList(s)) { + sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD4); + } else if (sc.GetRelative(-static_cast(strlen(s))-1) == '{' && + keywords5.InList(s) && sc.ch == '}') { // {keyword} exactly no spaces + sc.ChangeState(SCE_TCL_EXPAND); + } + if (keywords6.InList(s)) { + sc.ChangeState(SCE_TCL_WORD5); + } else if (keywords7.InList(s)) { + sc.ChangeState(SCE_TCL_WORD6); + } else if (keywords8.InList(s)) { + sc.ChangeState(SCE_TCL_WORD7); + } else if (keywords9.InList(s)) { + sc.ChangeState(SCE_TCL_WORD8); + } + } + expected = false; + sc.SetState(quote ? SCE_TCL_IN_QUOTE : SCE_TCL_DEFAULT); + } else if (sc.state == SCE_TCL_MODIFIER || sc.state == SCE_TCL_SUBSTITUTION) { + sc.SetState(SCE_TCL_DEFAULT); + } + } + } + if (atEnd) + break; + if (sc.atLineEnd) { + currentLine = styler.GetLine(sc.currentPos); + if (foldComment && sc.state == SCE_TCL_COMMENTLINE) { + if (currentLevel == 0) { + ++currentLevel; + commentLevel = true; + } + } else { + if (visibleChars && commentLevel) { + --currentLevel; + --previousLevel; + commentLevel = false; + } + } + int flag = 0; + if (!visibleChars) + flag = SC_FOLDLEVELWHITEFLAG; + if (currentLevel > previousLevel) + flag = SC_FOLDLEVELHEADERFLAG; + styler.SetLevel(currentLine, flag + previousLevel + SC_FOLDLEVELBASE + (currentLevel << 17) + (commentLevel << 16)); + + // Update the line state, so it can be seen by next line + if (sc.state == SCE_TCL_IN_QUOTE) + lineState = LS_OPEN_DOUBLE_QUOTE; + else if (prevSlash) { + if (sc.state == SCE_TCL_COMMENT || sc.state == SCE_TCL_COMMENTLINE) + lineState = LS_OPEN_COMMENT; + } + styler.SetLineState(currentLine, + (subBrace ? LS_BRACE_ONLY : 0) | + (expected ? LS_COMMAND_EXPECTED : 0) | lineState); + sc.SetState(SCE_TCL_DEFAULT); + prevSlash = false; + previousLevel = currentLevel; + lineState = LS_DEFAULT; + continue; + } + + if (prevSlash) { + prevSlash = (sc.state == SCE_TCL_COMMENT || sc.state == SCE_TCL_COMMENTLINE) && isspacechar(static_cast(sc.ch)); + continue; + } + + if (sc.atLineStart) { + visibleChars = false; + if (lineState == LS_OPEN_COMMENT) { + sc.SetState(SCE_TCL_COMMENT); + lineState = LS_DEFAULT; + continue; + } + if (lineState == LS_OPEN_DOUBLE_QUOTE) + sc.SetState(SCE_TCL_IN_QUOTE); + else + { + sc.SetState(SCE_TCL_DEFAULT); + expected = IsAWordStart(sc.ch)|| isspacechar(static_cast(sc.ch)); + } + } + + switch (sc.state) { + case SCE_TCL_NUMBER: + if (!IsANumberChar(sc.ch)) + sc.SetState(SCE_TCL_DEFAULT); + break; + case SCE_TCL_IN_QUOTE: + if (sc.ch == '"') { + sc.ForwardSetState(SCE_TCL_DEFAULT); + visibleChars = true; // necessary for a " as the first and only character on a line + goto next; + } else if (sc.ch == '[' || sc.ch == ']' || sc.ch == '$') { + sc.SetState(SCE_TCL_OPERATOR); + expected = sc.ch == '['; + sc.ForwardSetState(SCE_TCL_IN_QUOTE); + goto next; + } + prevSlash = sc.ch == '\\'; + continue; + case SCE_TCL_OPERATOR: + sc.SetState(SCE_TCL_DEFAULT); + break; + } + + if (sc.ch == '#') { + if (visibleChars) { + if (sc.state != SCE_TCL_IN_QUOTE && expected) { + sc.SetState(SCE_TCL_COMMENT); + expected = false; + } + } else + sc.SetState(SCE_TCL_COMMENTLINE); + } + + if (!isspacechar(static_cast(sc.ch))) { + visibleChars = true; + } + + if (sc.ch == '\\') { + prevSlash = true; + continue; + } + + // Determine if a new state should be entered. + if (sc.state == SCE_TCL_DEFAULT) { + if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { + sc.SetState(SCE_TCL_NUMBER); + } else if (IsAWordStart(sc.ch) & expected) { + sc.SetState(SCE_TCL_IDENTIFIER); + } else { + switch (sc.ch) { + case '\"': + sc.SetState(SCE_TCL_IN_QUOTE); + break; + case '{': + sc.SetState(SCE_TCL_OPERATOR); + expected = true; + ++currentLevel; + break; + case '}': + sc.SetState(SCE_TCL_OPERATOR); + --currentLevel; + break; + case '[': + case ']': + sc.SetState(SCE_TCL_OPERATOR); + expected = true; + break; + case '(': + case ')': + sc.SetState(SCE_TCL_OPERATOR); + break; + case ';': + expected = true; + break; + case '$': + subParen = 0; + if (sc.chNext != '{') { + sc.SetState(SCE_TCL_SUBSTITUTION); + } + else { + sc.ForwardSetState(SCE_TCL_OPERATOR); // { + sc.ForwardSetState(SCE_TCL_SUB_BRACE); + subBrace = true; + } + break; + case '-': + if (!IsADigit(sc.chNext)) + sc.SetState(SCE_TCL_MODIFIER); + break; + } + } + } + } + sc.Complete(); +} + +static const char * const tclWordListDesc[] = { + "TCL Keywords", + "TK Keywords", + "iTCL Keywords", + "tkCommands", + "expand" + "user1", + "user2", + "user3", + "user4", + 0 + }; + +// this code supports folding in the colourizer +LexerModule lmTCL(SCLEX_TCL, ColouriseTCLDoc, "tcl", 0, tclWordListDesc); diff --git a/scintilla/Makefile.am b/scintilla/Makefile.am index f70a655a..d4f29197 100644 --- a/scintilla/Makefile.am +++ b/scintilla/Makefile.am @@ -6,7 +6,6 @@ noinst_LIBRARIES=libscintilla.a CC=g++ AM_CXXFLAGS = -DGTK -DGTK2 -DSCI_LEXER -DG_THREADS_IMPL_NONE -#AM_CXXFLAGS = -DGTK -DGTK2 -DSCI_LEXER LEXER_SRCS= \ LexAsm.cxx \ @@ -23,7 +22,8 @@ LexPascal.cxx \ LexPerl.cxx \ LexPython.cxx \ LexRuby.cxx \ -LexSQL.cxx +LexSQL.cxx \ +LexTCL.cxx SRCS= \ CallTip.cxx \ diff --git a/src/filetypes.c b/src/filetypes.c index da40a5d3..a4c83514 100644 --- a/src/filetypes.c +++ b/src/filetypes.c @@ -389,6 +389,24 @@ void filetypes_init_types(void) filetypes_create_menu_item(filetype_menu, filetypes[GEANY_FILETYPES_RUBY]->title, filetypes[GEANY_FILETYPES_RUBY]); filetypes_create_newmenu_item(template_menu, filetypes[GEANY_FILETYPES_RUBY]->title, filetypes[GEANY_FILETYPES_RUBY]); +#define TCL + filetypes[GEANY_FILETYPES_TCL] = g_new0(filetype, 1); + filetypes[GEANY_FILETYPES_TCL]->id = GEANY_FILETYPES_TCL; + filetypes[GEANY_FILETYPES_TCL]->name = g_strdup("Tcl"); + filetypes[GEANY_FILETYPES_TCL]->has_tags = TRUE; + filetypes[GEANY_FILETYPES_TCL]->title = g_strdup(_("Tcl source file")); + filetypes[GEANY_FILETYPES_TCL]->extension = g_strdup("tcl"); + filetypes[GEANY_FILETYPES_TCL]->pattern = g_new0(gchar*, 4); + filetypes[GEANY_FILETYPES_TCL]->pattern[0] = g_strdup("*.tcl"); + filetypes[GEANY_FILETYPES_TCL]->pattern[1] = g_strdup("*.tk"); + filetypes[GEANY_FILETYPES_TCL]->pattern[2] = g_strdup("*.wish"); + filetypes[GEANY_FILETYPES_TCL]->pattern[3] = NULL; + filetypes[GEANY_FILETYPES_TCL]->style_func_ptr = styleset_tcl; + filetypes[GEANY_FILETYPES_TCL]->comment_open = g_strdup("#"); + filetypes[GEANY_FILETYPES_TCL]->comment_close = NULL; + filetypes_init_build_programs(filetypes[GEANY_FILETYPES_TCL]); + filetypes_create_menu_item(filetype_menu, filetypes[GEANY_FILETYPES_TCL]->title, filetypes[GEANY_FILETYPES_TCL]); + #define ALL filetypes[GEANY_FILETYPES_ALL] = g_new0(filetype, 1); filetypes[GEANY_FILETYPES_ALL]->id = GEANY_FILETYPES_ALL; diff --git a/src/filetypes.h b/src/filetypes.h index 4b08139b..5a5a652d 100644 --- a/src/filetypes.h +++ b/src/filetypes.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * $Id$ */ @@ -46,8 +46,9 @@ enum GEANY_FILETYPES_CAML, // 16 GEANY_FILETYPES_OMS, // 17 GEANY_FILETYPES_RUBY, // 18 - GEANY_FILETYPES_ALL, // 19 - GEANY_MAX_FILE_TYPES // 20 + GEANY_FILETYPES_TCL, // 19 + GEANY_FILETYPES_ALL, // 20 + GEANY_MAX_FILE_TYPES // 21 }; struct build_menu_items diff --git a/src/highlighting.c b/src/highlighting.c index 674a9260..672ff693 100644 --- a/src/highlighting.c +++ b/src/highlighting.c @@ -1337,6 +1337,7 @@ void styleset_python(ScintillaObject *sci) styleset_set_style(sci, SCE_P_STRINGEOL, GEANY_FILETYPES_PYTHON, 13); SSM(sci, SCI_SETPROPERTY, (sptr_t) "fold.comment.python", (sptr_t) "1"); + SSM(sci, SCI_SETPROPERTY, (sptr_t) "fold.quotes.python", (sptr_t) "1"); } @@ -2114,5 +2115,88 @@ void styleset_oms(ScintillaObject *sci) } +static void styleset_tcl_init(void) +{ + GKeyFile *config = g_key_file_new(); + GKeyFile *config_home = g_key_file_new(); + gchar *f = g_strconcat(app->configdir, G_DIR_SEPARATOR_S SUBDIR G_DIR_SEPARATOR_S, "filetypes.tcl", NULL); + + styleset_load_file(config, GEANY_DATA_DIR G_DIR_SEPARATOR_S "filetypes.tcl", G_KEY_FILE_KEEP_COMMENTS, NULL); + g_key_file_load_from_file(config_home, f, G_KEY_FILE_KEEP_COMMENTS, NULL); + + types[GEANY_FILETYPES_TCL] = g_new(style_set, 1); + styleset_get_hex(config, config_home, "styling", "default", "0x000000", "0xffffff", "false", types[GEANY_FILETYPES_TCL]->styling[0]); + styleset_get_hex(config, config_home, "styling", "comment", "0x0000ff", "0xffffff", "false", types[GEANY_FILETYPES_TCL]->styling[1]); + styleset_get_hex(config, config_home, "styling", "commentline", "0x0000ff", "0xffffff", "false", types[GEANY_FILETYPES_TCL]->styling[2]); + styleset_get_hex(config, config_home, "styling", "number", "0x007f00", "0xffffff", "false", types[GEANY_FILETYPES_TCL]->styling[3]); + styleset_get_hex(config, config_home, "styling", "operator", "0x101030", "0xffffff", "false", types[GEANY_FILETYPES_TCL]->styling[4]); + styleset_get_hex(config, config_home, "styling", "identifier", "0x0000a2", "0xffffff", "false", types[GEANY_FILETYPES_TCL]->styling[5]); + styleset_get_hex(config, config_home, "styling", "wordinquote", "0x7f007f", "0xffffff", "false", types[GEANY_FILETYPES_TCL]->styling[6]); + styleset_get_hex(config, config_home, "styling", "inquote", "0x7f007f", "0xffffff", "false", types[GEANY_FILETYPES_TCL]->styling[7]); + styleset_get_hex(config, config_home, "styling", "substitution", "0x991111", "0xffffff", "false", types[GEANY_FILETYPES_TCL]->styling[8]); + styleset_get_hex(config, config_home, "styling", "modifier", "0x7f007f", "0xffffff", "false", types[GEANY_FILETYPES_TCL]->styling[9]); + styleset_get_hex(config, config_home, "styling", "expand", "0x100000", "0xffffff", "false", types[GEANY_FILETYPES_TCL]->styling[10]); + styleset_get_hex(config, config_home, "styling", "wordtcl", "0x991111", "0xffffff", "true", types[GEANY_FILETYPES_TCL]->styling[11]); + styleset_get_hex(config, config_home, "styling", "wordtk", "0x00007f", "0xffffff", "true", types[GEANY_FILETYPES_TCL]->styling[12]); + styleset_get_hex(config, config_home, "styling", "worditcl", "0x991111", "0xffffff", "true", types[GEANY_FILETYPES_TCL]->styling[13]); + styleset_get_hex(config, config_home, "styling", "wordtkcmds", "0x00007f", "0xffffff", "true", types[GEANY_FILETYPES_TCL]->styling[14]); + styleset_get_hex(config, config_home, "styling", "wordexpand", "0x00007f", "0xffffff", "true", types[GEANY_FILETYPES_TCL]->styling[15]); + + types[GEANY_FILETYPES_TCL]->keywords = g_new(gchar*, 6); + styleset_get_keywords(config, config_home, "keywords", "tcl", GEANY_FILETYPES_TCL, 0, ""); + styleset_get_keywords(config, config_home, "keywords", "tk", GEANY_FILETYPES_TCL, 1, ""); + styleset_get_keywords(config, config_home, "keywords", "itcl", GEANY_FILETYPES_TCL, 2, ""); + styleset_get_keywords(config, config_home, "keywords", "tkcommands", GEANY_FILETYPES_TCL, 3, ""); + styleset_get_keywords(config, config_home, "keywords", "expand", GEANY_FILETYPES_TCL, 4, ""); + types[GEANY_FILETYPES_TCL]->keywords[5] = NULL; + + styleset_get_wordchars(config, config_home, GEANY_FILETYPES_TCL, GEANY_WORDCHARS); + filetypes_get_config(config, config_home, GEANY_FILETYPES_TCL); + + g_key_file_free(config); + g_key_file_free(config_home); + g_free(f); +} + + +void styleset_tcl(ScintillaObject *sci) +{ + + if (types[GEANY_FILETYPES_TCL] == NULL) styleset_tcl_init(); + + styleset_common(sci, 5); + + + SSM(sci, SCI_SETWORDCHARS, 0, (sptr_t) types[GEANY_FILETYPES_TCL]->wordchars); + SSM(sci, SCI_AUTOCSETMAXHEIGHT, 8, 0); + + SSM(sci, SCI_SETLEXER, SCLEX_TCL, 0); + + SSM(sci, SCI_SETKEYWORDS, 0, (sptr_t) types[GEANY_FILETYPES_TCL]->keywords[0]); + SSM(sci, SCI_SETKEYWORDS, 1, (sptr_t) types[GEANY_FILETYPES_TCL]->keywords[1]); + SSM(sci, SCI_SETKEYWORDS, 2, (sptr_t) types[GEANY_FILETYPES_TCL]->keywords[2]); + SSM(sci, SCI_SETKEYWORDS, 3, (sptr_t) types[GEANY_FILETYPES_TCL]->keywords[3]); + SSM(sci, SCI_SETKEYWORDS, 4, (sptr_t) types[GEANY_FILETYPES_TCL]->keywords[4]); + + styleset_set_style(sci, SCE_TCL_DEFAULT, GEANY_FILETYPES_TCL, 0); + styleset_set_style(sci, SCE_TCL_COMMENT, GEANY_FILETYPES_TCL, 1); + styleset_set_style(sci, SCE_TCL_COMMENTLINE, GEANY_FILETYPES_TCL, 2); + styleset_set_style(sci, SCE_TCL_NUMBER, GEANY_FILETYPES_TCL, 3); + styleset_set_style(sci, SCE_TCL_OPERATOR, GEANY_FILETYPES_TCL, 4); + styleset_set_style(sci, SCE_TCL_IDENTIFIER, GEANY_FILETYPES_TCL, 5); + styleset_set_style(sci, SCE_TCL_WORD_IN_QUOTE, GEANY_FILETYPES_TCL, 6); + styleset_set_style(sci, SCE_TCL_IN_QUOTE, GEANY_FILETYPES_TCL, 7); + styleset_set_style(sci, SCE_TCL_SUBSTITUTION, GEANY_FILETYPES_TCL, 8); + styleset_set_style(sci, SCE_TCL_MODIFIER, GEANY_FILETYPES_TCL, 9); + styleset_set_style(sci, SCE_TCL_EXPAND, GEANY_FILETYPES_TCL, 10); + styleset_set_style(sci, SCE_TCL_WORD, GEANY_FILETYPES_TCL, 11); + styleset_set_style(sci, SCE_TCL_WORD2, GEANY_FILETYPES_TCL, 12); + styleset_set_style(sci, SCE_TCL_WORD3, GEANY_FILETYPES_TCL, 13); + styleset_set_style(sci, SCE_TCL_WORD4, GEANY_FILETYPES_TCL, 14); + styleset_set_style(sci, SCE_TCL_WORD5, GEANY_FILETYPES_TCL, 15); + + SSM(sci, SCI_SETWHITESPACEFORE, 1, 0xc0c0c0); +} + diff --git a/src/highlighting.h b/src/highlighting.h index 090d12d8..7a630c82 100644 --- a/src/highlighting.h +++ b/src/highlighting.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * $Id$ */ @@ -79,4 +79,6 @@ void styleset_caml(ScintillaObject *sci); void styleset_oms(ScintillaObject *sci); +void styleset_tcl(ScintillaObject *sci); + #endif diff --git a/src/utils.c b/src/utils.c index a377e945..6a61f0ef 100644 --- a/src/utils.c +++ b/src/utils.c @@ -2217,6 +2217,7 @@ void utils_parse_compiler_error_line(const gchar *string) // the error output of python, perl and php -l on errors euals in "line xx", so they are "compatible" case GEANY_FILETYPES_PHP: case GEANY_FILETYPES_PERL: + case GEANY_FILETYPES_TCL: case GEANY_FILETYPES_PYTHON: { // File "HyperArch.py", line 37, in ? gchar *space = strchr(string, ' '); diff --git a/tagmanager/Makefile.am b/tagmanager/Makefile.am index 68bce9f7..7e1782f4 100644 --- a/tagmanager/Makefile.am +++ b/tagmanager/Makefile.am @@ -32,7 +32,7 @@ libtagmanager_a_SOURCES =\ docbook.c\ make.c\ asm.c\ - tex.c\ + latex.c\ pascal.c\ perl.c\ ruby.c\ @@ -40,6 +40,7 @@ libtagmanager_a_SOURCES =\ php.c\ python.c\ regex.c\ + tcl.c\ sh.c\ ctags.c\ entry.c\ diff --git a/tagmanager/tex.c b/tagmanager/latex.c similarity index 98% rename from tagmanager/tex.c rename to tagmanager/latex.c index ec59cbb8..6792e216 100644 --- a/tagmanager/tex.c +++ b/tagmanager/latex.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: tex.c 283 2006-04-27 22:52:09Z eht16 $ * * Copyright (c) 2000-2001, Jérôme Plût * Copyright (c) 2006, Enrico Tröger @@ -217,7 +217,7 @@ static void findTeXTags(void) } } -extern parserDefinition* TexParser (void) +extern parserDefinition* LaTeXParser (void) { static const char *const extensions [] = { "tex", "sty", "idx", NULL }; parserDefinition * def = parserNew ("LaTeX"); diff --git a/tagmanager/parsers.h b/tagmanager/parsers.h index 4048abe0..9667e057 100644 --- a/tagmanager/parsers.h +++ b/tagmanager/parsers.h @@ -23,13 +23,14 @@ PerlParser, \ PhpParser, \ PythonParser, \ - TexParser, \ + LaTeXParser, \ AsmParser, \ ConfParser, \ SqlParser, \ DocBookParser, \ CssParser, \ RubyParser, \ + TclParser, \ ShParser #endif /* _PARSERS_H */ diff --git a/tagmanager/tcl.c b/tagmanager/tcl.c new file mode 100644 index 00000000..7c18c118 --- /dev/null +++ b/tagmanager/tcl.c @@ -0,0 +1,82 @@ +/* +* +* Copyright (c) 2000-2001, Darren Hiebert +* +* This source code is released for free distribution under the terms of the +* GNU General Public License. +* +* This module contains functions for generating tags for TCL scripts. +*/ + +/* +* INCLUDE FILES +*/ +#include "general.h" /* must always come first */ + +#include + +#include "parse.h" +#include "read.h" +#include "vstring.h" + +/* +* DATA DEFINITIONS +*/ +typedef enum { + K_PROCEDURE +} tclKind; + +static kindOption TclKinds [] = { + { TRUE, 'f', "function", "procedures" } +}; + +/* +* FUNCTION DEFINITIONS +*/ + +static void findTclTags (void) +{ + vString *name = vStringNew (); + const unsigned char *line; + + while ((line = fileReadLine ()) != NULL) + { + int i; + + if (line [0] == '\0' || line [0] == '#') + continue; + + /* read first word */ + for (i = 0 ; line [i] != '\0' && ! isspace (line [i]) ; ++i) + ; + + if (strncmp ((const char*) line, "proc", (size_t) 4) == 0) + { + const unsigned char *cp = line + i; + while (isspace ((int) *cp)) + ++cp; + while (line [i] != '\0' && ! isspace ((int) *cp)) + { + vStringPut (name, (int) *cp); + ++cp; + } + vStringTerminate (name); + makeSimpleTag (name, TclKinds, K_PROCEDURE); + vStringClear (name); + } + } + vStringDelete (name); +} + +extern parserDefinition* TclParser (void) +{ + static const char *const extensions [] = { "tcl", "tk", "wish", NULL }; + parserDefinition* def = parserNew ("Tcl"); + def->kinds = TclKinds; + def->kindCount = KIND_COUNT (TclKinds); + def->extensions = extensions; + def->parser = findTclTags; + return def; +} + +/* vi:set tabstop=8 shiftwidth=4: */