enhance.cxx

Go to the documentation of this file.
00001 // @(#)root/editline:$Id: enhance.cxx 30349 2009-09-22 10:35:20Z axel $
00002 // Author: Mary-Louise Gill, 2009
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include "el.h"
00013 #include <stack>
00014 #include <set>
00015 #include <string>
00016 
00017 #include "TROOT.h"
00018 #include "TInterpreter.h"
00019 
00020 using namespace std;
00021 
00022 void setKeywordColors(const char* colorTab, const char* colorBracket, const char* colorBadBracket);
00023 int selectColor(const char* str);
00024 void highlightKeywords(EditLine_t* el);
00025 int matchParentheses(EditLine_t* el);
00026 void colorWord(EditLine_t* el, int first, int num, int color);
00027 void colorBrackets(EditLine_t* el, int open, int close, int color);
00028 char** rl_complete2ROOT(const char*, int, int);
00029 
00030 // int values for colour highlighting
00031 int color_class = 4;           // NCurses COLOR_BLUE
00032 int color_type = 4;            // NCurses COLOR_BLUE
00033 int color_bracket = 2;         // NCurses COLOR_GREEN
00034 int color_badbracket = 1;      // NCurses COLOR_RED
00035 
00036 /**
00037  *   Sets the colours to use for highlighting keywords (types and classnames),
00038  *   matching bracket pairs, mismatched brackets and tab completion.
00039  *   Overrides the default colour settings:
00040  *   class and type: 4 (blue)
00041  *   bracket pair:   2 (green)
00042  *   bad bracket:   1 (red)
00043  */
00044 void
00045 setKeywordColors(int colorType, int colorBracket, int colorBadBracket) {
00046    color_class = colorType;
00047    color_type = colorType;
00048    color_bracket = colorBracket;
00049    color_badbracket = colorBadBracket;
00050 } // setKeywordColors
00051 
00052 
00053 /*
00054  *      Use gRoot to establish keywords known to root.
00055  *
00056  */
00057 void
00058 highlightKeywords(EditLine_t* el) {
00059    typedef std::set<int> HashSet_t;
00060    static HashSet_t sHashedKnownTypes;
00061 
00062    TString sBuffer(el->fLine.fBuffer, el->fLine.fLastChar - el->fLine.fBuffer);
00063 
00064    TString keyword;
00065    Ssiz_t posNextTok = 0;
00066    Ssiz_t posPrevTok = 0;
00067 
00068    // regular expression inverse of match expression to find end of match
00069    while (sBuffer.Tokenize(keyword, posNextTok, "[^a-zA-Z0-9_]")) {
00070       Ssiz_t toklen = posNextTok - posPrevTok;
00071 
00072       if (posNextTok == -1) {
00073          toklen = sBuffer.Length() - posPrevTok;
00074       }
00075       TString tok = sBuffer(posPrevTok, toklen);
00076       Ssiz_t pos = posPrevTok + tok.Index(keyword);
00077       int color = -1;
00078 
00079       if (gROOT->GetListOfTypes()->FindObject(keyword)) {
00080          color = color_type;
00081       } else if (gInterpreter->CheckClassInfo(keyword, kFALSE)) {
00082          color = color_class;
00083       }
00084       colorWord(el, pos, keyword.Length(), color);
00085       posPrevTok = posNextTok;
00086    }
00087 } // highlightKeywords
00088 
00089 
00090 /** if buffer has content, check each char to see if it is an opening bracket,
00091     if so, check for its closing one and return the indices to both
00092  * alt:
00093  * check each char for a match against each type of open and close bracket
00094  * if open found, push index onto a seperate stack for each type of bracket
00095  * if close found, pop previous value off relevant stack
00096  * and pass both pointers to highlight()
00097  */
00098 int
00099 matchParentheses(EditLine_t* el) {
00100    static const int amtBrackets = 3;
00101    int bracketPos = -1;
00102    int foundParenIdx = -1;
00103    char bTypes[amtBrackets][2];
00104 
00105    bTypes[0][0] = '(';
00106    bTypes[0][1] = ')';
00107    bTypes[1][0] = '{';
00108    bTypes[1][1] = '}';
00109    bTypes[2][0] = '[';
00110    bTypes[2][1] = ']';
00111    //static char bTypes[] = "(){}[]"; with strchr(bTypes, sBuffer[bracketPos])
00112 
00113    // CURRENT STUFF
00114    // create a string of the buffer contents
00115    std::string sBuffer = "";
00116 
00117    for (char* c = el->fLine.fBuffer; c < el->fLine.fLastChar; c++) {
00118       sBuffer += *c;
00119    }
00120 
00121    // check whole buffer for any highlighted brackets and remove colour info
00122    for (int i = 0; i < (el->fLine.fLastChar - el->fLine.fBuffer); i++) {
00123       if (el->fLine.fBufColor[i].fForeColor == color_bracket || el->fLine.fBufColor[i].fForeColor == color_badbracket) {
00124          el->fLine.fBufColor[i] = -1;                      // reset to default colours
00125          term__repaint(el, i);
00126       }
00127    }
00128 
00129    // char* stack for pointers to locations of brackets
00130    stack<int> locBrackets;
00131 
00132    if (!sBuffer.empty()) {
00133       int cursorPos = el->fLine.fCursor - el->fLine.fBuffer;
00134       bracketPos = cursorPos;
00135 
00136       // check against each bracket type
00137       int bIndex = 0;
00138 
00139       for (bIndex = 0; bIndex < amtBrackets; bIndex++) {
00140          // if current char is equal to opening bracket, push onto stack
00141          if (sBuffer[bracketPos] == bTypes[bIndex][0]) {
00142             locBrackets.push(bracketPos);
00143             foundParenIdx = 0;
00144             break;
00145          } else if (sBuffer[bracketPos] == bTypes[bIndex][1]) {
00146             locBrackets.push(bracketPos);
00147             foundParenIdx = 1;
00148             break;
00149          }
00150       }
00151 
00152       // current cursor char is not an open bracket, and there is a previous char to check
00153       if (foundParenIdx == -1 && bracketPos > 0) {
00154          //check previously typed char for being a closing bracket
00155          bracketPos--;
00156          // check against each bracket type
00157          bIndex = 0;
00158 
00159          for (bIndex = 0; bIndex < amtBrackets; bIndex++) {
00160             // if current char is equal to closing bracket, push onto stack
00161             if (sBuffer[bracketPos] == bTypes[bIndex][1]) {
00162                locBrackets.push(bracketPos);
00163                foundParenIdx = 1;
00164                break;
00165             }
00166          }
00167       }
00168 
00169       // no bracket found on either current or previous char, return.
00170       if (foundParenIdx == -1) {
00171          return foundParenIdx;
00172       }
00173 
00174       // iterate through remaining letters until find a matching closing bracket
00175       // if another open bracket of the same type is found, push onto stack
00176       // and pop on next closing bracket match
00177       int step = 1;
00178 
00179       if (foundParenIdx == 1) {
00180          step = -1;
00181       }
00182 
00183       for (int i = bracketPos + step; i >= 0 && i < (int)sBuffer.size(); i += step) {
00184          //if current char is equal to another opening bracket, push onto stack
00185          if (sBuffer[i] == bTypes[bIndex][foundParenIdx]) {
00186             // push index of bracket
00187             locBrackets.push(i);
00188          }
00189          //if current char is equal to closing bracket
00190          else if (sBuffer[i] == bTypes[bIndex][1 - foundParenIdx]) {
00191             // pop previous opening bracket off stack
00192             locBrackets.pop();
00193 
00194             // if previous opening was the last entry, then highlight match
00195             if (locBrackets.empty()) {
00196                colorBrackets(el, bracketPos, i, color_bracket);
00197                break;
00198             }
00199          }
00200       }
00201 
00202       if (!locBrackets.empty()) {
00203          colorBrackets(el, bracketPos, bracketPos, color_badbracket);
00204       }
00205    }
00206 
00207    return foundParenIdx;
00208 } // matchParentheses
00209 
00210 
00211 /**
00212  *      Highlight a word within the buffer.
00213  *      Requires the start and end index of the word, and the color pair index (class or type).
00214  *      Writes colour info for each char in range to el->fLine.bufcol.
00215  *      Background colour is set to the same as the current terminal background colour.
00216  *      Foreground (text) colour is set according to the type of word being highlighted (e.g. class or type).
00217  */
00218 void
00219 colorWord(EditLine_t* el, int first, int num, int textColor) {
00220    int bgColor = -1;            // default background
00221    bool anyChange = false;
00222 
00223    // add colour information to el.
00224    for (int index = first; index < first + num; ++index) {
00225       bool changed = el->fLine.fBufColor[index].fForeColor != textColor;
00226       anyChange |= changed;
00227       el->fLine.fBufColor[index].fForeColor = textColor;
00228       el->fLine.fBufColor[index].fBackColor = bgColor;
00229 
00230       if (changed) {
00231          term__repaint(el, index);
00232       }
00233    }
00234 
00235    if (anyChange) {
00236       term__setcolor(-1);
00237    }
00238 } // colorWord
00239 
00240 
00241 /*
00242  *      Set the colour information in the SEditLine_t buffer,
00243  *      Then call repaint to repaint the chars with the new colour information
00244  */
00245 void
00246 colorBrackets(EditLine_t* el, int open, int close, int textColor) {
00247    int bgColor = -1;            // default background
00248 
00249    el->fLine.fBufColor[open].fForeColor = textColor;
00250    el->fLine.fBufColor[open].fBackColor = bgColor;
00251    term__repaint(el, open);
00252 
00253    el->fLine.fBufColor[close].fForeColor = textColor;
00254    el->fLine.fBufColor[close].fBackColor = bgColor;
00255    term__repaint(el, close);
00256 
00257    term__setcolor(-1);
00258 }

Generated on Tue Jul 5 14:11:38 2011 for ROOT_528-00b_version by  doxygen 1.5.1