`

怎样支持自动缩进

阅读更多

怎样支持自动缩进

来自http://www.cppprog.com/2009/1111/176_3.html

在VS里编写C++代码时,输入回车换行后会保持和上一行的缩进一致,输入"{'字符后回车还会帮我们多缩进一次,输入'}'后又能自动退回。我们的编辑器也要实现这个功能。

现在再仔细了解一下Scintilla的通知消息(http://scintilla.sourceforge.net/ScintillaDoc.html#Notifications),除了前面用到的页边点击事件外,还有很多事件非常有用。

实现自动缩进功能我们要关心的事件通知是SCN_CHARADDEDSCN_UPDATEUI

  • 当用户输入一个字符时,SCN_CHARADDED事件触发,SCNotification的ch成员保存了输入的字符。
  • 当更新文档界面时,SCN_UPDATEUI事件触发。输入字符,改变字体风格,改变选区都会引起界面更新

演示代码

改写TForm1::WndProc,处理这两个事件,我们的编辑器支持自动缩进啦

  1. void __fastcall TForm1::WndProc(Messages::TMessage &Message)
  2. {
  3.     TForm::WndProc(Message);
  4.  
  5.     if(Message.Msg == WM_NOTIFY)
  6.     {
  7.         ...
  8.         // 处理自动缩进
  9.         static int LastProcessedChar = 0;
  10.         //在CharAdded事件中记录最后输入的字符
  11.         if(notify->nmhdr.code == SCN_CHARADDED)
  12.         {
  13.             LastProcessedChar = notify->ch;
  14.         }
  15.         // 在UpdateUI事件中处理缩进
  16.         if(notify->nmhdr.code == SCN_UPDATEUI && LastProcessedChar!=0)
  17.         {
  18.             int pos = SendEditor(SCI_GETCURRENTPOS); //取得当前位置
  19.             int line = SendEditor(SCI_LINEFROMPOSITION,pos); //取得当前行
  20.             //如果最后输入的字符是右括号的话就自动让当前行缩进和它匹配的左括号所在行一致
  21.             if( strchr("})>]",LastProcessedChar) &&
  22.                 isspace(SendEditor(SCI_GETCHARAT,pos-2)) && //要求右括号左边是空白字符
  23.                 LastProcessedChar!=0)
  24.             {
  25.                 //找前一个单词起始位置,这里用它来确定右括号左边是否全是空白字符
  26.                 int startpos = SendEditor(SCI_WORDSTARTPOSITION,pos-1,false);
  27.                 int linepos = SendEditor(SCI_POSITIONFROMLINE,line); //当前行起始位置
  28.                 if(startpos == linepos) //这样相当于判断右括号左边是否全是空白字符
  29.                 {
  30.                     int othpos = SendEditor(SCI_BRACEMATCH,pos-1); //得到对应的左括号所在的位置
  31.                     int othline = SendEditor(SCI_LINEFROMPOSITION,othpos);  //左括号所在行
  32.                     int nIndent = SendEditor(SCI_GETLINEINDENTATION,othline);//左括号所在行的缩进值
  33.                     // 替换右括号前面的空白字符,使之与左括号缩进一致
  34.                     char space[1024];
  35.                     memset(space,' ',1024);
  36.                     SendEditor(SCI_SETTARGETSTART, startpos);
  37.                     SendEditor(SCI_SETTARGETEND, pos-1);
  38.                     SendEditor(SCI_REPLACETARGET,nIndent,(sptr_t)space);
  39.                 }
  40.             }
  41.             // 如果输入的是回车,则保持与上一行缩进一致
  42.             // 如果上一行最后有效字符为左括号,就多缩进四个空格
  43.             if(LastProcessedChar == ' ')
  44.             {
  45.                 if(line > 0)
  46.                 {
  47.                     // 得到上一行缩进设置
  48.                     int nIndent = SendEditor(SCI_GETLINEINDENTATION,line-1);
  49.                     // 查找上一行最后一个有效字符(非空白字符)
  50.                     int nPrevLinePos = SendEditor(SCI_POSITIONFROMLINE,line-1);
  51.                     int c = ' ';
  52.                     for(int p = pos-2;
  53.                         p>=nPrevLinePos && isspace(c);
  54.                         p--, c=SendEditor(SCI_GETCHARAT,p));
  55.                     // 如果是左括号,就多缩进四格
  56.                     if(c && strchr("{([<",c)) nIndent+=4;
  57.                     // 缩进...
  58.                     char space[1024];
  59.                     memset(space,' ',1024);
  60.                     space[nIndent] = 0;
  61.                     SendEditor(SCI_REPLACESEL, 0, (sptr_t)space);
  62.                 }
  63.             }
  64.             LastProcessedChar = 0;
  65.         }
  66.     }
  67. }

下面是代码中用到的Scintilla命令的简单介绍

  • SCN_CHARADDED事件记录最后输入的字符,在SCN_UPDATEUI事件中处理缩进。
  • 当输入回车时(LastProcessedChar == ' '),我们只需要保证新行和前一行的缩进相同就可以了。
  • SCI_GETLINEINDENTATION命令可以取得指定行的缩进数(即行首的空格数目)。
  • SCI_REPLACESEL命令用指定字符串替换选择区域
  • SCI_GETCURRENTPOS命令取得当前位置
  • SCI_GETCHARAT命令取得指定位置的字符
  • SCI_LINEFROMPOSITION命令取得指定位置所在的行号
  • SCI_POSITIONFROMLINE命令取得指定行号的起始位置
  • SCI_WORDSTARTPOSITION命令取得指定位置所在单词的起始位置,如xxx|xx,(|代表指定位置),那么它会返回|xxxxx的位置。同样还有SCI_WORDENDPOSITION命令。
  • SCI_BRACEMATCH取得括号的另一半位置,如指定位置的字符是'}'时,它返回匹配的'{'所在的位置。
  • SCI_SETTARGETSTART和SCI_SETTARGETEND设置TARGET的起始和始止位置,SCI_REPLACETARGET命令用指定字符串替换TARGET指定范围内的字符。
分享到:
评论

相关推荐

    代码编辑器(支持自动缩进,语法高亮,代码折叠,函数提示,行号显示)

    3.支持自动代码缩进 int main() { while(true) { printf("great"); } } 4.支持行号显示,如程序左显示 5.支持函数参数自动提示功能,初步实现了CreateWindow(...), WinMain()函数,待扩展 ...

    PyQt5+Sintilla的python编辑器,支持代码高亮,自动补全,自动缩进,运行,行标记

    支持代码高亮,自定义补全(拥有基础补全功能),文件保存打开,检测缩进,代码行标记,你甚至可以简单的修改接口,改成任意编程语言(包括你自己的编程语言)的接口,还有代码高亮以及自定义自动补全,尤其适合编程...

    VB6精简版,支持win7 64位,带代码自动缩进,最好用的精简版

    打开程序报错的,关掉错误提示框就行,或者去掉“外接程序管理器”里面的vbinlineASM和增强查找插件 的启动和加载。 十分好用的精简版,找了好多个版本才找到的,可能跟站里的重复,毕竟没办法全部测试过。

    BS端代码编辑器,可集成所有web程序,支持上百种开发语言,有自动提示联想,对比,语法高亮,自动缩进等等特点

    自动完成(XML) 代码折叠 可配置的键绑定 Vim,Emacs和Sublime Text绑定 搜索和替换界面 支架和标签匹配 支持拆分视图 Linter集成 混合字体大小和样式 各种主题 能够调整大小以适应内容 内联和阻止小部件 可编程...

    Dev-cpp 5.9.0 2015年1月25日最新版

    一款很小巧的编译器,支持C/C++,支持Win8,有简体中文可选 又拥有很强大的功能,自动缩进,代码补全 转C++时找了很久,才找到的编译器

    far-indent:自动从code.google.compfar-indent导出

    使用TAB自动缩进(目前,Far支持使用空格自动缩进) 处理c,cpp和Java文件的{}括号 笔记: Do not forget to switch on Autoindent option on to make last two features work Menu -&gt; Options -&gt; Editor ...

    Linux下搭建强大VIM开发环境 (支持 Qt4 自动补全)

    支持c/c++语言自动缩进方式 支持c函数, c++类自动补全功能 完美支持中文 还有其他功能介绍和使用说明请看 Read Me.txt 安装方法: 只需解压后在终端运行 ./install.sh 如果运行不了, 执行 chmod +x install.sh 测试...

    (转)keil mdk 汉化补丁与keil 自动格式化代码

    (转)keil mdk 汉化补丁与keil 自动格式化代码工具,支持win7 win8.1亲测可用.安装完成后,替换文件即可。

    eric5-5.0.2

    7.支持自动缩进,会自动判断if, while等语句。 8.编辑器支持代码折叠 9.支持第三方插件。 10.很多小工具。比如正则表达式生成/测试器。 11.支持宏录制。 12.与QtDesigner(PyQt4的界面设计器)结合得很好,使得GUI程序...

    Pyzo 4.10.2.7z

    支持自动缩进。 自动确定加载文件时的缩进宽度。 支持评论和取消注释所选行。 查找/替换(也支持正则表达式)。 多种字体的选择,默认情况下,Pyzo有两种漂亮的字体。 断点用于调试。 Introspection 可选自动...

    GsEditor-GrADS脚本编辑器2.0绿色版

    编辑器支持行号的显示,支持自动缩进,还具有标尺的功能,使用的批量注释功能让你再也不用一个个的输入注释符。 软件内置了数据库,可以备份和恢复您的GS文件,也便于您高效的组织和利用现有的GS文件。 您还可以在...

    在Windows上编译、调试LINUX程序-XBuildDev

    XBuildStudio© 是运行... 强大的编辑功能,支持自动缩进[正在进行]。 支持多个工程管理。 编译及错误定位。 支持单步调试,变量实时显示。 设置和查看断点。 调用栈、线程查看。 函数导航,快速定位[正在进行]。

    在Windows上编译、调试LINUX程序: XBuildDev

    XBuildStudio© 是运行...强大的编辑功能,支持自动缩进[正在进行]。 支持多个工程管理。 编译及错误定位。 支持单步调试,变量实时显示。 设置和查看断点。 调用栈、线程查看。 函数导航,快速定位[正在进行]。

    代码编辑器

    小插件,一个代码编辑器,挺好用的,可代替记事本之类的

    Arduino-ide-2.0.4-Windows-64bit版本

    IDE界面直观友好,支持自动缩进和语法高亮,使编程更加便捷。此外,Arduino IDE拥有庞大的社区支持,用户可以在社区中获取丰富的教程、示例代码和项目分享。无论是初学者还是资深开发者,Arduino IDE都是进行Arduino...

    Notepad2-Mod V4.2.25(代替记事本)绿色版.rar

    支持将制表符作为空格插入,设置自动换行及行标记等,支持文本自动缩进,支持单词自动完成,自动关闭HTML/XML。PS:运行批处理“替换系统记事本.bat”可以代替系统自带的记事本,如果想恢复可以使用恢复批处理来完成...

    Editra(跨平台文本编辑器)v0.7.20官方中文多语安装版

    Editra(跨平台文本编辑器)是一个支持多平台的文本编辑器,可以支持基本语法和二十种语言,使用方便,可以用颜色标注重点部分,...4、自动缩进 5、自动补完/调用提示(Python) 6、支持搜索查找功能 7、多种颜色主题

    Erato for mac 1.4.1简单漂亮的Markdown文本编辑器 导出HTML和PDF 最新破解版

    自动缩进的代码块 将您的文件导出为 HTML 或 PDF, GitHub 味降价: 围栏的代码块: 友好的换行符 任务列表7 I8 自动 escaping_of_underlined_words& s" 在应用程序设置中切换开/关 额外的功能: 支持山狮系统 Mac...

    PyCharm代码整体缩进,反向缩进的方法

    解决pycharm回车之后不能换行或不能缩进的问题对pycharm代码整体左移和右移缩进快捷键的介绍pycharm设置注释颜色的方法Pycharm在创建py文件时,自动添加文件头注释的实例在Pycharm中对代码进行注释和缩进的方法详解

    notepad2 4.2.25(x64)中文绿色版.rar

    可以设置自动换行、自动缩进文本、自动关闭HTML/XML、自动完成单词,支持的编码包括(ANSI/Unicode/UTF-8等等)。内置多种语法支持,可以对语法进行高亮显示,支持代码折叠以及使用表达式对字符进行搜索与替换。在打开...

Global site tag (gtag.js) - Google Analytics