`

怎样支持自动缩进

阅读更多

怎样支持自动缩进

来自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指定范围内的字符。
分享到:
评论

相关推荐

    vba自动缩进工具

    "vba自动缩进工具"是专门针对VBA代码进行格式化和美化的一种实用程序,它可以帮助程序员提高代码可读性和维护性。 VBA代码通常需要遵循一定的编码规范,其中就包括适当的缩进。缩进不仅使代码看起来整洁,还能够...

    自动缩进VBA代码

    自动缩进VBA代码的工具就是为了实现这一目的,帮助程序员快速整理代码,使其更易于理解和调试。 "自动缩进VBA代码.exe" 是一个可能的实用程序,它专门设计用来自动格式化VBA代码,包括在VB或VBA环境中添加适当的...

    VB代码自动缩进工具

    VB代码自动缩进工具是一款专为Visual Basic编程语言设计的实用辅助软件,它极大地提升了VB程序员的代码编写效率和代码可读性。在VB编程中,代码的缩进和排列对于阅读和理解代码逻辑至关重要,尤其在处理大量或复杂的...

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

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

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

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

    wps文本首行自动缩进设置.docx

    ### WPS文档中设置首行自动缩进的详细步骤及应用 #### 一、引言 在撰写文档时,为了使文章结构清晰、格式统一,经常需要对段落进行缩进处理。WPS Office作为一款功能强大的办公软件,提供了丰富的文字处理功能,...

    html格式化源码(tab符自动缩进)

    "tab符自动缩进"是指在处理HTML源码时,通过插入制表符(tab)来使元素层级关系更加直观。这通常是通过编程工具或在线代码格式化器实现的。 在编写或修改HTML代码时,手动进行缩进可能会耗时且容易出错。因此,...

    DIV+CSS实现的框架,仿frameset,支持左侧缩进

    这个名为"DIV+CSS实现的框架,仿frameset,支持左侧缩进"的项目,旨在提供一种与传统`frameset`类似的功能,但利用更现代、更灵活的`CSS`布局方法来实现。`frameset`是HTML4时代的特性,它允许开发者将一个网页分割...

    emacs缩进问题

    在Emacs中,`electric-indent-mode`是默认开启的功能,它会自动根据当前语言的语法规则进行缩进。对于C/C++编程,`c-mode`和`c++-mode`是专门的模式,它们内置了对代码缩进的支持。你可以通过以下命令在Emacs中切换...

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

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

    Java_Android库可以轻松创建一个代码编辑器或IDE,支持任何语言和主题,具有自动完成自动缩进片段和更多功能.zip

    这个Java/Android库就是为了满足这样的需求而设计的,它允许开发者快速地构建具备代码编辑能力的界面,支持多种编程语言和自定义主题,并且包含了丰富的特性,如自动完成、自动缩进和代码片段等。 首先,我们要理解...

    c#源码 类似QQ缩进(放到屏幕边缘自动缩到里面去)

    在C#编程中,"类似QQ缩进"的特性通常指的是窗口或控件的自动吸附功能,这在桌面应用开发中十分常见。QQ等聊天软件的界面设计中,当用户将窗口拖动到屏幕边缘时,窗口会自动调整大小以适应屏幕边缘,这种功能为用户...

    VB 设置段落缩进

    RichTextBox是VB中常用于显示和编辑富文本的控件,支持多种格式,包括设置段落缩进。你可以通过修改`SelectionIndent`属性来设置当前选区的首行缩进。例如: ```vb RichTextBox1.SelectionIndent = 30 '设置30个...

    VS开发工具 脚本缩进括号自动匹配插件

    JSEnhancements插件自动处理缩进,当用户在编写代码时,它可以智能地根据当前的代码块进行自动缩进,无需手动调整,极大地提高了编写代码的速度。同时,它还能在打开或关闭大括号(如花括号{})时自动调整缩进,保持...

    VB代码格式缩进.zip

    2. **自动缩进**:自动缩进功能是编程环境中的一个重要特性,它能够帮助程序员快速调整代码的缩进,使得嵌套结构如循环和条件语句更加清晰。VB代码格式自动缩进源码就是实现这一功能的代码实现。 3. **源码**:源码...

    Markup带缩进(Unicode)

    这种改进后的XML解析器或生成器可以自动为XML文档添加缩进,使得文档结构更易于理解。 在描述中提到的“源码是在改进的基础上,稍修改了一下在Unicode字符集下编译通过”,这意味着原始的Markup代码可能不完全支持...

    vimz中设置回车换行缩进

    - **`shiftwidth`**:指定自动缩进时使用的字符数,默认值为8。 - **`expandtab`**:如果开启,Vim会将制表符转换为相应数量的空格,默认值为关闭状态。 - **`autoindent`**:如果开启,Vim会在新行上复制前一行的...

    IndentGuide For VS2010 缩进对齐插件

    当然,如果需要自定义设置,如改变缩进线的颜色、宽度或启用/禁用特定语言的支持,可以在Visual Studio的“工具”菜单中找到“IndentGuide选项”,进行个性化配置。 此外,IndentGuide还具备一定的智能性。它能根据...

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

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

Global site tag (gtag.js) - Google Analytics