實現代碼編輯器


    上一次曾經發布過一篇如何實現一個代碼編輯器。今年工作中得空,所以對這個編輯器進一步做了些更新,把名字改成了從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
    軟件界面:
       


一、編輯控件
 除了上一次寫到的一些內容外,主要在編輯控件的語法高亮上做了修改。
 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.光標在屏幕中的位置的計算,要根據光標前面數據的字體來實時計算寬度。
 
二、函數列表
    對於代碼編輯軟件來說,函數符號列表功能是必備的,就算是純寫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) );

 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,太強悍了,讓我非常的佩服。

三、腳本管理
    讓編輯軟件支持腳本是必要的,不僅僅可以對常用的功能提供擴展。我實現了類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上可以看看相關的實現方法,算是講得比較清楚的吧。
   
四、數據存儲
    數據存儲在不同的軟件中都必須用到,我這里主要是配置的存儲和腳本的存儲,正好我寫了個key-value存儲系統,所以這個直接拿來用就非常合適了,效率也不錯。跟直接讀寫硬盤沒什么區別,省去了煩人的fopen,fread,fwrite,fclose調用,直接用windows的api更是煩人,所以寫這樣一個簡單的庫,非常方便。
    http://www.cnblogs.com/linxr/p/3252541.html,在這里可以看到實現方法和下載到源代碼。我覺得這個簡單的key-value存儲庫,比我寫的解釋器,和這個編輯器本身更加實用,所有的軟件都可以用,接口也很簡單。無法就是open,set,get,close四個函數。省去了文件操作的各種麻煩。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM