`

(转)用Scintilla让程序支持语法高亮

阅读更多

用Scintilla让程序支持语法高亮

来自http://www.cppprog.com/2009/1030/171.html

 

Scintilla是一个免费、跨平台、支持语法高亮的编辑控件。它完整支持源代码的编辑和调试,包括语法高亮、错误指示、代码完成(code completion)和调用提示(call tips)。能包含标记(marker)的页边(margin)可用于标记断点、折叠和高亮当前行。

Scintilla是一个免费、跨平台、支持语法高亮的编辑控件。它完整支持源代码的编辑和调试,包括语法高亮、错误指示、代码完成 (code completion)和调用提示(call tips)。能包含标记(marker)的页边(margin)可用于标记断点、折叠和高亮当前行。

可以从这里下载Scintilla库:http://scintilla.sourceforge.net/ScintillaDownload.html

这里有Scinilla相关的库下载,比如wxScintilla就是Scintilla的wxWidgets移植版。http://www.scintilla.org/ScintillaRelated.html

另外,Scintilla的作者为了演示这个东东的功能,编写了一个叫SciTE的演示程序。不过这个程序的功能已经强大到足以作为我 们的常用代码编辑器,很值得下载下来学习学习。

老规矩,还是从编译说起

偶只在Windows下编译过,所以只好说说Windows环境下的编译方法。对于Linux,没试过(丢人-_-)

下载、解压略过不提

首先进入scintilla的win32目录:

cd scintilla\win32
  • 对于mingw,输入:
    mingw32-make
  • 对于VC6以上版本,输入:
    nmake -f scintilla.mak
  • 对于VC6(没试过,从Readme里看来的),输入:
    nmake -f scintilla_vc6.mak
  • 对于C++Builder,输入:
    make -fscintilla.mak

编译完成后,在bin目录里会得到Scintilla.dll和SciLexer.dll文件,SciLexer.dll是包含了语法解析器 (Lexer)的Scintilla控件,一般来说我们只要用它就可以了。

需要说明的是,不管是用什么编译器生成的DLL文件,都可以供给其它编译器使用(就象系统DLL一样,任何编译器都能使用),所以不用为各种编译器都编译 一份。

如果觉得生成的SciLexer.dll太大的话,可以考虑去除自带的部分语法解析器。比如你打算只用它来高亮C++代码的话,可以:

  1. 进到src目录里,移除除LexCPP.cxx以外的所有Lex*.cxx文件
  2. 执行LexGen.py重建make文件和KeyWords.cxx文件(需要安装Python)。
  3. 重新按前面的方法编译,这样生成的SciLexer.dll就只带有C++语法解析器了,体积也大小减小了(我VC编译的结果是从1.4M减小到 206K)。

启用Scintilla作为编辑控件

要启用Scintilla,首先当然是要加载之前编译的DLL文件啦~~

::LoadLibrary(_T("SciLexer.dll"));

SciLexer.dll加载后会自动以"Scintilla"作为类名注册一个窗体类,我们只要直接用这个类名建立窗体就可以了:

::CreateWindow(_T("Scintilla"),...);

演示(在C++Builder下编写)

由于Scintilla主要是窗体操作,为了减少不必要的窗体代码(主要是偷懒外加推广一下C++Builder,呵呵),这里使用C++Builder 来写演示程序。对于一些C++Builder的VCL库特有的东东,后面会有解释的。

首先新建一个窗体应用程序,

然后在WinMain里载入SciLexer.dll:

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    LoadLibrary(_T("SciLexer.dll"));
    ...

最后,在TForm1的构造里建立Scintilla窗体:

#define SCINT_ID 1010

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    ::CreateWindow(_T("Scintilla"),
        NULL, WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_VISIBLE,
        0,0,ClientWidth,ClientHeight,
        Handle,
        (HMENU)SCINT_ID, HInstance, NULL);
}

很简单,是吧?对于Scintilla来说,没什么好解释的了。

这里主要给不了解C++Builder的童鞋介绍一下VCL的东东,以便于接下来的讲解和代码阅读(以及移植到其它编译器中)。

  • TForm1是一个C++Builder自动生成的窗体类,它继承自TForm,可以把它看成是WS_OVERLAPPEDWINDOW风格的HWND的 封装。
  • ClientWidth和ClientHeight是TForm的属性,看名字就知道它是客户区(ClientRect)的宽和高
  • Handle也是TForm的属性,就是该窗体的HWND
  • HInstance不用解释了吧,这是VCL的一个全局变量。

现在,我们的成果是这样的:


现在,看上去还比较土,接下来我们开始配置它,为使它成为可与VS媲美的代码编程器而战!

Scintilla是一个免费、跨平台、支持语法高亮的编辑控件。它完整支持源代码的编辑和调试,包括语法高亮、错误指示、代码完成(code completion)和调用提示(call tips)。能包含标记(marker)的页边(margin)可用于标记断点、折叠和高亮当前行。

配置Scintilla的两种方法

配置Scintilla控件是通过向该控件发送配置命令实现的,各种配置命令可以在doc目录下找到(或者是这里http://scintilla.sourceforge.net/ScintillaDoc.html),后面的大部分事情都是在介绍这些配置命令。

有两种方法来发送配置命令,一种是直接使用SendMessage API。另一种是取得直接控制函数,通过函数来执行配置命令。

在Windows下,第二种方法要比第一种快得多。

直接控制函数的定义为:

typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam);

后三个参数和SendMessage的后三个参数一样。
SciFnDirect的第一个参数用于指定具体的Scintilla窗体,它类似于窗体的HWND又不完全相同,姑且也称之为句柄吧。它是用一个配置命 令取得的,下面马上就要讲到。

取得直接控制函数和句柄的方法是:

SciFnDirect fnDirect = (SciFnDirect)SendMessage(hwndEditor,SCI_GETDIRECTFUNCTION,0,0);
sptr_t ptrDirect = (sptr_t)SendMessage(hwndEditor,SCI_GETDIRECTPOINTER,0,0);

取得这两样东西以后,就可以直接执行配置命令了,如:

m_fnDirect(fnDirect, SCI_CLEARALL, 0, 0);

演示代码:编写成员函数SendEditor,用于配置之前建立的Scintilla控件。

  1. #include <Scintilla.h>
  2. #include <SciLexer.h>
  3.  
  4. class TForm1 : public TForm
  5. {
  6. __published:    // IDE-managed Components
  7. private:    // User declarations
  8.     SciFnDirect m_fnDirect;
  9.     sptr_t m_ptrDirect;
  10. public:        // User declarations
  11.     __fastcall TForm1(TComponent* Owner);
  12.     sptr_t SendEditor(unsigned int iMessage, uptr_t wParam = 0, sptr_t lParam = 0)
  13.     {
  14.         return m_fnDirect(m_ptrDirect, iMessage, wParam, lParam);
  15.     }
  16. };
  17.  
  18. #define SCINT_ID 1010
  19. __fastcall TForm1::TForm1(TComponent* Owner)
  20.     : TForm(Owner)
  21. {
  22.     HWND hwndEditor = ::CreateWindow(_T("Scintilla"),
  23.         NULL, WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_VISIBLE,
  24.         0,0,ClientWidth,ClientHeight,
  25.         Handle,
  26.         (HMENU)SCINT_ID, HInstance, NULL);
  27.     m_fnDirect = (SciFnDirect)SendMessage(hwndEditor,SCI_GETDIRECTFUNCTION,0,0);
  28.     m_ptrDirect = (sptr_t)SendMessage(hwndEditor,SCI_GETDIRECTPOINTER,0,0);
  29. }

 

有了前面的SendEditor控制函数,我们就可以配置语法高亮了,下面这段代码可以使我们的Scintilla控件显示C++语法高亮代码:

const char* g_szKeywords=
    "asm auto bool break case catch char class const "
    "const_cast continue default delete do double "
    "dynamic_cast else enum explicit extern false finally "
    "float for friend goto if inline int long mutable "
    "namespace new operator private protected public "
    "register reinterpret_cast register return short signed "
    "sizeof static static_cast struct switch template "
    "this throw true try typedef typeid typename "
    "union unsigned using virtual void volatile "
    "wchar_t while";
...
SendEditor(SCI_SETLEXER, SCLEX_CPP); //C++语法解析
SendEditor(SCI_SETKEYWORDS, 0, (sptr_t)g_szKeywords);//设置关键字
// 下面设置各种语法元素前景色
SendEditor(SCI_STYLESETFORE, SCE_C_WORD, 0x00FF0000);   //关键字
SendEditor(SCI_STYLESETFORE, SCE_C_STRING, 0x001515A3); //字符串
SendEditor(SCI_STYLESETFORE, SCE_C_CHARACTER, 0x001515A3); //字符
SendEditor(SCI_STYLESETFORE, SCE_C_PREPROCESSOR, 0x00808080);//预编译开关
SendEditor(SCI_STYLESETFORE, SCE_C_COMMENT, 0x00008000);//块注释
SendEditor(SCI_STYLESETFORE, SCE_C_COMMENTLINE, 0x00008000);//行注释
SendEditor(SCI_STYLESETFORE, SCE_C_COMMENTDOC, 0x00008000);//文档注释(/**开头)

要支持语法高亮,要做三件事:

一、选定语法解析器

语法解析器用于把一大段代码分解成一个个的单词(token),另外还用于代码折叠的控制(后面会说到)。

选定语法解析器的命令是SCI_SETLEXER,如:

SendEditor(SCI_SETLEXER, SCLEX_CPP);

除了SCLEX_CPP以外,还有SCLEX_HTML、SCLEX_PERL、SCLEX_SQL、SCLEX_VB等一大堆,定 义在SciLexer.h里。现代的IDE应该可以定位SCLEX_CPP定义,它周围的SCLEX_XXX就是其它的语法解析器。

另外,也可以用SCI_SETLEXERLANGUAGE命令,如:

SendEditor(SCI_SETLEXERLANGUAGE, 0, (sptr_t)"cpp");

SCI_SETLEXERLANGUAGE接受的是一个字符串参数,这个字符串定义于代码解析器源代码(src\lex*.cxx) 最后面LexerModule开头的那行代码,那里的第三个参数就是。

二、设置关键字

语法解析只负责把代码拆分开,至于哪些是关键字,还得我们来指定。

这种方式带来了些许的灵活性,比如我们要高亮一种自定义的语言,这种语言的风格与C++类似(如Java、C#、php等),我们也 可以选定SCLEX_CPP作为语法解析器,然后定义自己的关键字。(所以不需要把各种解析器都编译进DLL文件里)

设置关键字的命令是SCI_SETKEYWORDS。它的wParam用于指定关键字种类,可以是0~8即9种类型,这样我们可以做 更细致的区分,如把关键字for if和int bool区分显示。lParam指定关键字,以空格分隔。    

三、设置文本元素对应的字体风格

即字体、前景色、背景色、斜体粗体等

设置字体风格的命令以SCI_STYLE作为前缀,这组命令比较多,为了不浪费篇幅,偶这里只列举几个,其它的可以参考这里 (http://scintilla.sourceforge.net/ScintillaDoc.html#StyleDefinition)。

SCI_STYLESETBACK(int styleNumber, int colour) //设置背景色
SCI_STYLESETFORE(int styleNumber, int colour) //设置前景色
SCI_STYLESETFONT(int styleNumber, char *fontName) //设置字体
SCI_STYLESETSIZE(int styleNumber, int sizeInPoints)//设置字号
SCI_STYLESETBOLD(int styleNumber, bool bold) //设置粗体

这里的styleNumber是指文本元素,如关键字、行号、控制字串等。前面代码中的SCE_C_XXXX是C++解析器分解出的 语法相关的元素。另外还有STYLE_DEFAULT(默认)、STYLE_LINENUMBER(行号)、STYLE_BRACELIGHT(括号匹 配)、STYLE_BRACEBAD(括号失配)、STYLE_CONTROLCHAR(控制字符)、STYLE_INDENTGUIDE(缩进线)、 STYLE_CALLTIP(调用提示)。

SCI_STYLECLEARALL //把所有文本元素设置成与STYLE_DEFAULT相同的风格

Scintilla文档建议的顺序是先向STYLE_DEFAULT设置一些通用风格,然后再用SCI_STYLECLEARALL 把所有元素风格重置成与STYLE_DEFAULT一致,最后单独设置其它元素。

演示,我们的编辑器支持C++高亮啦!

  1. #include <Scintilla.h>
  2. #include <SciLexer.h>
  3. ...
  4. void TForm1::setCppStyle()
  5. {
  6.     const char* szKeywords1=
  7.         "asm auto break case catch class const "
  8.         "const_cast continue default delete do double "
  9.         "dynamic_cast else enum explicit extern false "
  10.         "for friend goto if inline mutable "
  11.         "namespace new operator private protected public "
  12.         "register reinterpret_cast return signed "
  13.         "sizeof static static_cast struct switch template "
  14.         "this throw true try typedef typeid typename "
  15.         "union unsigned using virtual volatile while";
  16.     const char* szKeywords2=
  17.         "bool char float int long short void wchar_t";
  18.     // 设置全局风格
  19.     SendEditor(SCI_STYLESETFONT, STYLE_DEFAULT,(sptr_t)"Courier New");
  20.     SendEditor(SCI_STYLESETSIZE, STYLE_DEFAULT,10);
  21.     SendEditor(SCI_STYLECLEARALL);
  22.     //C++语法解析
  23.     SendEditor(SCI_SETLEXER, SCLEX_CPP);
  24.     SendEditor(SCI_SETKEYWORDS, 0, (sptr_t)szKeywords1);//设置关键字
  25.     SendEditor(SCI_SETKEYWORDS, 1, (sptr_t)szKeywords2);//设置关键字
  26.     // 下面设置各种语法元素风格
  27.     SendEditor(SCI_STYLESETFORE, SCE_C_WORD, 0x00FF0000);   //关键字
  28.     SendEditor(SCI_STYLESETFORE, SCE_C_WORD2, 0x00800080);   //关键字
  29.     SendEditor(SCI_STYLESETBOLD, SCE_C_WORD2, TRUE);   //关键字
  30.     SendEditor(SCI_STYLESETFORE, SCE_C_STRING, 0x001515A3); //字符串
  31.     SendEditor(SCI_STYLESETFORE, SCE_C_CHARACTER, 0x001515A3); //字符
  32.     SendEditor(SCI_STYLESETFORE, SCE_C_PREPROCESSOR, 0x00808080);//预编译开关
  33.     SendEditor(SCI_STYLESETFORE, SCE_C_COMMENT, 0x00008000);//块注释
  34.     SendEditor(SCI_STYLESETFORE, SCE_C_COMMENTLINE, 0x00008000);//行注释
  35.     SendEditor(SCI_STYLESETFORE, SCE_C_COMMENTDOC, 0x00008000);//文档注释(/**开头)
  36.  
  37.     SendEditor(SCI_SETCARETLINEVISIBLE, TRUE);
  38.     SendEditor(SCI_SETCARETLINEBACK, 0xb0ffff);
  39. }
  40.  
  41. __fastcall TForm1::TForm1(TComponent* Owner)
  42.     : TForm(Owner)
  43. {
  44.     ...
  45.     setCppStyle();
  46. }

看上去不错,如果你愿意,还可以加上当前行高亮功能:

SendEditor(SCI_SETCARETLINEVISIBLE, TRUE);
SendEditor(SCI_SETCARETLINEBACK, 0xb0ffff);

最后,建议把TAB宽度由默认的8改为4(依个人习惯~~)

SendEditor(SCI_SETTABWIDTH, 4);

现在,我们的成果是这样的:

 


分享到:
评论

相关推荐

    Scintilla 【代码编辑器控件,支持语法高亮】

    Scintilla不仅具备基本的文本编辑功能,还特别强调了对源代码的处理能力,支持语法高亮显示,这使得在编写和查看代码时能有更好的视觉体验和工作效率。 Scintilla的设计目标是跨平台,可以在多种操作系统上运行,如...

    支持语法高亮的编辑器

    标题中的“支持语法高亮的编辑器”是指一类具有特殊功能的文本编辑工具,它们能够对程序员在编写代码时使用的各种编程语言的关键字、符号、注释等进行颜色区分,以提高代码的可读性和编辑体验。这类编辑器通常会根据...

    scintilla语法高亮显示2.11

    包括语法高亮显示,错误指示,代码自动完成以及代码提示等。而且在左边的空白处(margin),可以显示调试代码中非常有用的显示断点以及显示当前运行行等功能。而且,自定义风格的功能比其他大部分编辑器控件都开放,它...

    scintilla 3.72 语法着色器

    1. **语法高亮**:Scintilla支持多种编程语言的语法着色,通过识别关键字、注释、字符串和数值等不同类型的代码元素,用不同的颜色显示,提高代码的可读性。用户还可以自定义颜色方案。 2. **自动完成**:提供代码...

    scintilla 语法高亮编辑器源代码

    License for Scintilla and SciTE Copyright 1998-2003 by Neil Hodgson &lt;neilh@scintilla.org&gt; All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation ...

    纯SDK写的 支持语法高亮的编辑控件

    标题中的“纯SDK写的 支持语法高亮的编辑控件”指的是一个使用软件开发工具包(SDK)创建的编辑器组件,它具备对C和C++编程语言的语法高亮显示功能。这样的编辑控件在开发IDE(集成开发环境)、代码编辑器或者任何...

    改版SciTE 增加了cpp语法高亮

    标题“改版SciTE 增加了cpp语法高亮”表明这是一个关于SciTE编辑器的更新版本,特别强调了它现在支持C++(cpp)语言的语法高亮显示。SciTE,全称“Scientific ToolWindow Editor”,是由Scott Lysle开发的一个轻量级...

    Scintilla控件使用Demo

    - Scintilla是一个C++库,提供了强大的文本编辑功能,包括多种语言的语法高亮,支持Unicode和UTF-8编码。 - 它不仅提供了基本的文本编辑功能,如复制、粘贴、查找、替换,还支持自定义样式、字体、颜色,以及代码...

    Scintilla控件编程资料

    Scintilla 的一大亮点是支持语法高亮,这使得它可以识别并突出显示不同编程语言的关键字、字符串、注释等。开发者可以通过配置特定的语言样式来实现这一功能,Scintilla 提供了多种样式属性,如字体、颜色、背景色等...

    多文档语法高亮编辑器[MDIEditorusingScintilla.rar]-精品源代码

    这是一个关于创建多文档界面(MDI)语法高亮编辑器的源代码项目,使用的库是Scintilla。Scintilla是一个流行的开源文本编辑组件,它提供了丰富的文本编辑功能,包括语法高亮、自动完成、括号匹配等。在这个项目中,...

    Scintilla中文文档+带标签

    Scintilla是一个开源的源代码编辑器控件,支持多种编程语言的语法高亮和代码折叠功能。它最初由Neil Hodgson开发,并作为Lexilla的一部分,提供了一个灵活的词法分析器引擎。Scintilla适用于Windows、GTK+、OSX以及...

    支持语法高亮的SciTE简单小巧的文本编辑器

    SciTE 是个开源的优秀且小巧功能强大的编辑器!它支持代码高亮、自动完成、代码折叠、括号匹配、自定义模块等!...还可以自己定义语言,并为自己的语言设置语法高亮。 像vc vs中的代码折叠也是支持的。

    Scintilla_and_SciTE

    Scintilla 是 C++ 实现的文本编辑控件,它提供了丰富的语法高亮、自动完成、代码折叠、括号匹配等特性,广泛应用于各种编程环境和编辑器中。Scintilla 的设计目标是提供一个强大且可定制的文本编辑核心,开发者可以...

    在MFC中使用Scintilla进行语法着色

    Scintilla是一个强大的文本编辑组件,它支持语法高亮、代码折叠、自动完成等功能,广泛应用于各种编程环境和文本编辑器。在MFC(Microsoft Foundation Classes)框架中使用Scintilla,可以为你的Windows应用程序增添...

    VS2015编译的scintilla的64位的库文件和头文件

    Scintilla是一个免费、跨平台、支持语法高亮的编辑控件。以下是对Scintilla库的详细介绍: 一、主要功能 Scintilla完整支持源代码的编辑和调试,具体包括: 语法高亮:能够根据不同的编程语言对代码进行语法高亮...

    显示行号的语法高亮编辑器

    综上所述,"显示行号的语法高亮编辑器"的核心是Scintilla组件,通过使用ScintillaWrapper等工具,开发者可以轻松地在自定义的应用程序中集成这一强大功能,提高编程效率。而提供的文件清单则揭示了这个编辑器的开发...

    scintilla的MFC封装

    Scintilla是一个强大的文本编辑组件,它被广泛用于各种编程环境和文本编辑器中,因为它提供了丰富的特性,如语法高亮、代码折叠、自动完成等。MFC(Microsoft Foundation Classes)是微软提供的一套C++类库,用于...

    Scintilla开源库使用指南.doc

    - **语法高亮**:能够自动识别并突出显示不同编程语言的关键字、字符串、注释等元素。 - **错误指示**:可在代码编辑过程中实时标示语法错误或警告。 - **代码完成**:提供自动补全功能,帮助开发者快速编写代码。 -...

    scintilla文本编辑器

    在实际开发中,Scintilla通常与一个图形用户界面库(如wxWidgets或Qt)结合使用,以构建完整的编辑器应用程序。开发者可以利用这些库提供的窗口和布局管理功能,同时结合Scintilla的强大文本处理能力,创建出美观且...

    c++ scintilla

    Scintilla是一款开源的文本编辑组件,主要由C++编写,设计目的是提供一个高质量的文本编辑器基础,供开发者在各种应用程序中使用。它不仅具备基本的文本编辑功能,如文本选择、剪切、复制、粘贴等,还支持语法高亮、...

Global site tag (gtag.js) - Google Analytics