实现代码编辑器

    上一次曾经发布过一篇如何实现一个代码编辑器。今年工做中得空,因此对这个编辑器进一步作了些更新,把名字改为了从CuteC改为了CEditor。主要是重写了软件的界面(最终还原朴素),重写了编辑控件语法高亮的着色方式,还有增长了一个简单的SSH客户端和SFTP文件编辑的功能。感受基本的功能已经实现了,因此再次写点东西记录一下。而且发布一下编辑控件的源代码,有兴趣的可下载下来看看,虽然代码写得比较乱。
    上个版本:http://www.cnblogs.com/linxr/archive/2011/10/30/2229256.html
    编辑控件源码连接:http://files.cnblogs.com/linxr/LEdit.rar
    软件下载连接:http://files.cnblogs.com/linxr/CEditor.rar
    软件界面:
        html


1、编辑控件
 除了上一次写到的一些内容外,主要在编辑控件的语法高亮上作了修改。
 1. 原来的颜色信息是在绘制每行时,动态分词查找关键字,造成一个颜色数组供绘制模块使用。这种方式的优势就是逻辑简单,绘制代码很容易编写。可是缺点就是,每次绘制一行,都要从新产生颜色数组,影响效率;其二,在一些场合下,高亮不是依赖于关键字,这时候这种方法就无能为力了。
 2. 考虑到上面的缺点,对编辑控件作了修改。去除了颜色数组,改用标注信息来标注颜色字体信息。因此行数据通过着色以后再也不是原来的内容了。
 
    例如一行数据:
    int main( int argc, char ** argv );
    那么通过着色后,该行的数据会变成:
    \ec3,0~int\ezc~ main( \ec3,0~int\ezc~ argc, \ec3,0~char\ezc~ ** argv );
    其中,int和char被着色,标注信息为:
    \ec3,0~ 和 \ezc~
    着色信息以\e(0x1b)开始,以~结束。c表示颜色,z表示还原格式格式。
    
     着色完成后,绘制模块在进行绘制文本信息时,从头至尾,扫描字符串,根据着色信息,不断的设置还原DC的颜色信息,直到绘制完成。
 3. 标注颜色带来了一些额外的问题,主要表如今:
    a.光标位置到字符串中的位置的转换的计算。
    b.获取编辑器的内容时,要清除全部的标注信息,影响必定的性能。
    c.计算tab键的宽度时,不能用tab键在字符串中的位置来计算,要考虑标注信息。
    d.光标在屏幕中的位置的计算,要根据光标前面数据的字体来实时计算宽度。
 
2、函数列表
    对于代码编辑软件来讲,函数符号列表功能是必备的,就算是纯写C的人来讲,有一个函数列表会大大提升滚动查找代码的效率。我虽然写了一个C语言的解释器,对符号的解析稍做修改就能够实现,可是各类各样的语言,我就无能为力了。好在有ctags.exe,他能够支持很是的语言符号分析。我仍是直接拿来用吧,而后再加上一个树形控件,就能实现简单实用的功能。
    我调用ctags.exe的代码片断,主要是调用了ctags.exe,将结果保存到一个文件,而后咱们再解析这个文件:
   
 CString strParam;
 CString strTags = strFilePath + _T(".tags.txt");
 strParam.Format( _T("-f \"%s\" --language-force=C++ -n \"%s\"" ), strTags.GetBuffer(0), strFilePath.GetBuffer(0) );windows

 SHELLEXECUTEINFO   sei;
 ZeroMemory( &sei, sizeof(SHELLEXECUTEINFO) );
 sei.cbSize = sizeof(SHELLEXECUTEINFO);
 sei.fMask = SEE_MASK_NOCLOSEPROCESS;
 sei.hwnd = NULL;
 sei.lpVerb = NULL;
 sei.lpFile = "ctags.exe";
 sei.lpParameters = strParam.GetBuffer(0);
 sei.lpDirectory = CLxrFile::GetExecutePath().GetBuffer(0);
 sei.nShow = SW_HIDE;
 sei.hInstApp = NULL;
 ShellExecuteEx(&sei);
 WaitForSingleObject( sei.hProcess, INFINITE );
 /*
 ** 能够看到就是调用了ShellExecuteEx,可是有几个地方能够提一下:
 ** 1. sei.nShow = SW_HIDE; 这使得进程启动时不会显示控制台窗口。
 ** 2. WaitForSingleObject( sei.hProcess, INFINITE );
 **    等待进程结束,这个很重要,否则ctags启动后,咱们没法同步获取结果。
 */
 
    
    ctags.exe支持的语言,能够用命令 ctags.exe --list-languages 查看:
        Asm
        Asp
        Awk
        Basic
        BETA
        C
        C++
        C#
        Cobol
        Eiffel
        Erlang
        Fortran
        HTML
        Java
        JavaScript
        Lisp
        Lua
        Make
        Pascal
        Perl
        PHP
        Python
        REXX
        Ruby
        Scheme
        Sh
        SLang
        SML
        SQL
        Tcl
        Vera
        Verilog
        Vim
        YACC
    能够看到,他几乎涵盖了全部流行的语言,而他的执行文件大小只有256kb,太强悍了,让我很是的佩服。api

3、脚本管理
    让编辑软件支持脚本是必要的,不只仅能够对经常使用的功能提供扩展。我实现了类C的解析执行,因此对简单的计算功能,软件的功能,都能给外部脚本提供接口函数,让脚本轻松的操做编辑器,或者作一些好玩的事情。我主要作的是将脚本直接映射到右键菜单,当添加一个脚本时,他将直接被添加进右键菜单。而且支持多级目录。
    例如,我实现了几个接口供脚本使用:
    
  int ceditor_exe_2( char * cmd, char * out );
  该函数用于执行cmd指令,out为输出结果。cmd为编辑器的的命令,形如rep_sel$hello world$。
  int ceditor_exe_4( char * cmd, char * p1, char *p2, char * out );
  该函数效果同ceditor_exe_2,可是cmd仅是命令,p1,p2分别是两个参数。
  int clear();
  该函数用于清除输出框的内容。
  int ceditor_hotkey( char * ctrlKeys, int vKey, char * scriptPath );
  该函数用于注册热键。数组

    C的解释器,你们能够看我之前发过的文章,代码能够在CSDN上面找到,搜索"xrc C语言解释器"就能找到,或者试试这个连接:http://download.csdn.net/download/linxren/4204728。在cnblogs上能够看看相关的实现方法,算是讲得比较清楚的吧。
   
4、数据存储
    数据存储在不一样的软件中都必须用到,我这里主要是配置的存储和脚本的存储,正好我写了个key-value存储系统,因此这个直接拿来用就很是合适了,效率也不错。跟直接读写硬盘没什么区别,省去了烦人的fopen,fread,fwrite,fclose调用,直接用windows的api更是烦人,因此写这样一个简单的库,很是方便。
    http://www.cnblogs.com/linxr/p/3252541.html,在这里能够看到实现方法和下载到源代码。我以为这个简单的key-value存储库,比我写的解释器,和这个编辑器自己更加实用,全部的软件均可以用,接口也很简单。没法就是open,set,get,close四个函数。省去了文件操做的各类麻烦。编辑器

相关文章
相关标签/搜索