SharpDevelop浅析_4_TextEditor_自动完成、代码折叠……

SharpDevelop浅析_4_TextEditor_自动完成、代码折叠……


SharpDevelop浅析_4_TextEditor_自动完成、代码折叠……

Parser及其应用: Code Completion, Method Insight, Class Scout ...

1、Demo界面及功能解释
2、Parser实现概述
3、Parser应用: MouseHover Tooltip
4、Parser应用: CodeCompletion & MethodInsight
5、Parser应用: QuickClassBrowserPanel
6、Parser应用: Folding
7、总结
Demo下载
1、Demo界面及功能解释
启动并打开任一 .cs 文件后,界面如下:

自动完成界面如下:

可见新增功能如下(仅支持.cs文件):
a, 鼠标停留在方法、属性等位置时,会显示出相关的文档描述tooltip
b, 输入时支持自动完成
c, 编辑窗口顶部有类列表和成员(方法、变量等)列表下拉框用以快速浏览、定位
d, 编辑窗口左侧有折叠线用以方法、类等的代码折叠
相应的Demo工程中新增项目如下:
a, SharpEditor:   包含扩展TextEditor的控件, Dom结构, ParserService, 自动完成功能代码等
b, NRefactor :    代码解析功能
c, CSharpBinding: 对应 .cs 文件的具体实现支持

[题外话]: 
关于代码解析(Parser)相关的代码,我没看懂,所以在这里只说个大概,更多地谈谈Parser的使用;抛砖引玉,希望有相关经验的网友提供详尽的分析。
前两周工作上的项目实施,每天都搞得比较累,所以这篇文章到现在才写了出来,明天是大年三十了,这个系列的文章也只剩下一篇Windows Form Designer,只能等过了年再放上来喽。
另外,这个系列写完后,暂不打算深究一些没明白的细节,接下来想看下os workflow 或 CommunityServer...


2、Parser实现概述

(1)首先,SharpEditor项目中的Dom下定义了以下重要类:
a, IDecoration及其子类:   代码表现的辅助对象,如IClass, IMethod, IProperty等
b, ResolveResult及其子类: 分析结果对象,如MethodResolveResult, TypeResolveResult等
c, 其它重要类:           IExpressionFinder, IParser, IResolve, ICompilationUnit 等

(2)重要服务类:
ParserService:   提供 GetExpressionFinder(), Resolve(), ParseFile()等重要方法,相关重要类: ProjectContentRegistry, DefaultProjectContent, ReflectionProjectContent等
AmbienceService: 提供 IAmbience的实现类用以将分析结果转换为相应的字符描述

(3)Parser分析步骤:
以鼠标悬浮的Tooltip显示为例:DebuggerService根据文件类型返回对应的IExpressionFinder实现类,再根据鼠标位置找到并返回ExpressionResult对象,然后找到适当的IResolver实现类调用Resolve()方法返回结果ResolveResult对象,最后由相应的IAmbience实现类转换成结果字符,并调用e.ShowToolTip(toolTipText);显示。

(4)对于.NET默认类库的分析转换:
默认引进的命名空间的类结构和文档说明一般可以在"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\"目录下找到(如System.dll和System.xml),但是如果每次都要重新分析dll代码结构和xml注释显然是比较花费时间的,于是SharpDevelop采用的方式是将分析过的数据(Dom下的类结构表示数据?,二进制的.dat文件)存储到"C:\Documents and Settings\michael\Local Settings\Temp\SharpDevelop"下,代码结构存储到DomCacheDebug目录下,文档注释存储到DocumentationCacheDebug目录下。
首先在ParserService的CreateDefaultProjectContent()中加载默认命名空间的引用:

CreateDefaultProjectContent()

其中ProjectContentRegistry的GetProjectContentForReference()方法如下:

GetProjectContentForReference()

可以看到DomPersistence类的作用即在加载或保存dll的代码结构数据, 如果尚未有分析过的数据,则在ReflectionProjectContnet类的构造函数中加以分析,同时调用XmlDoc类的相关方法加载、保存文档注释数据。

(5)对于文件的转换:
[略]


3、Parser应用: MouseHover Tooltip

注意在SharpEditor项目中有个DebuggerService类,它提供了一个重要方法如下:

BindTextAreaEvent()

此方法即用以绑定需要鼠标悬浮提示的TextEditor控件,在SharpPad项目的Open菜单类方法中调用此类绑定编辑控件。
注意上面的方法中可以看到ICSharpCode.TextEditor控件是通过其TextArea的ToolTipRequest事件公开给外部,用以分析并由外部提供ToolTip数据,而TextArea_ToolTipRequest(object sender, ToolTipRequestEventArgs e)方法中根据鼠标位置分析出要显示的数据后,最终调用e.ShowToolTip(toolTipText);用以设置提供数据。

TextArea_ToolTipRequest()


4、Parser应用: CodeCompletion & MethodInsight

ICSharpCode.TextEditor控件使用ICompletionData类以及ICompletionDataProvider接口(GenerateCompletionData()方法)定义数据自动完成列表的数据及其提供者: SharpEditor项目中的AbstractCodeCompletionDataProvider类中由GetExpression()及AddResolveResults()两个辅助方法生成数据,代码如下:

AbstractCodeCompletionDataProvider 类

CommentCompletionDataProvider类提供注释的自动完成,相关代码如下:

CommentCompletionDataProvider 类

类似地,ICSharpCode.TextEditor控件提供了IInsightDataProvider接口(GetInsightData()方法),SharpEditor项目中实现类MethodInsightDataProvider和IndexerInsightDataProvider提供相关数据。

除了上面需要提供数据的类外,还要绑定TextEditor的TextArea的KeyEventHandler事件(详见SharpEditor项目的SharpDevelopTextAreaControl.cs),其中辅助类的处理代码如下:

KeyEventHandler 事件响应


5、Parser应用: QuickClassBrowserPanel

QuickClassBrowserPanel即编辑窗口顶部的类及成员快速浏览窗口,其实现如下:
首先在SharpDevelopTextAreaControl类中重写override void OnFileNameChanged(EventArgs e)方法,即打开新文件时,调用ActivateQuickClassBrowserOnDemand()来根据是否有能够分析此文件的Parser来决定是否显示控件,如果可以显示,则实例化出一个新对象,并添加进来。实例化QuickClassBrowserPanel对象的相关代码如下:

QuickClassBrowserPanel

可以看到类、成员列表的ComboBox数据的填充是在textAreaControl.ActiveTextAreaControl.Caret.PositionChanged事件后执行,因为光标位置的改变可能需要同步更新顶部列表框的显示;注意两个列表的列表项使用自定义类ComboBoxItem, 包括成员的Line, Column等信息;该类中绑定两个列表的SelectedIndexChange事件用以在编辑器中定位相应的类或成员位置:

ComboBoxSelectedIndexChanged()


6、Parser应用: Folding

ICSharpCode.TextEditor控件提供了IFoldingStrategy接口用以定义代码折叠需实现的方法:

IFoldingStrategy 接口

SharpEditor项目中,SharpDevelopTextAreaControl在构造函数中指明了FoldingStrategy:

SharpDevelopTextAreaControl 构造函数

同样需要在打开新文件时调用更新代码折叠标签,代码折叠FoldMarker生成的具体实现详见SharpEditor项目的ParserFoldingStrategy.cs


7、总结

上面简要介绍了Parser的部分实现, 期待有相关经验的网友指定我的理解错误或给予补充解释。
以及Parser的部分应用:MouseHover Tooltip, CodeCompletion & MethodInsight, QuickClassBrowserPanel, Folding;SharpDevelop中的其它应用如类视图ClassBrowser, 对象浏览AssemblyPad(SharpDevelop2.0源码中未见到?).

时间: 2024-10-09 02:33:25

SharpDevelop浅析_4_TextEditor_自动完成、代码折叠……的相关文章

NetBeans自定义代码折叠块,类似vs中的#region

//<editor-fold defaultstate="collapsed" desc="测试代码折叠"> echo '<script type="text/javascript">'; echo "alert('当前类目下有文章,不能删除!');"; echo "history.go(-1)"; echo "</script>"; exit;//&

0007 vim代码折叠功能

问题:怎样在vim中实现代码折叠功能? 解决方法:直接使用vim自带的快捷键和命令,便可以实现功能强大的折叠 小试折叠: 1 :set fdm=marker 在vim中执行该命令 2 5G 将光标跳转到第5行 3 zf10G 折叠第5行到第10行的代码,vim会在折叠的开始和结束自动添加三个连续的花括号作为标记 4 zR 打开所有折叠 5 zM 关闭所有折叠 6 zE 删除所有的折叠标签 7 退出vim窗口再次打开,执行2-6步.依然可以折叠,但是没有标记了.重新打开后折叠信息会丢失. 折叠方法

vim代码折叠命令

1. 折叠方式 可用选项 'foldmethod' 来设定折叠方式:set fdm=*****. 有 6 种方法来选定折叠:           manual           手工定义折叠 indent             更多的缩进表示更高级别的折叠 expr                用表达式来定义折叠 syntax             用语法高亮来定义折叠 diff                  对没有更改的文本进行折叠 marker            对文中的标志

VIM 代码折叠

VIM 代码折叠 VIM代码折叠方式可以用"foldmethod"选项来设置,如: set foldmethod=indent 有6种方式来折叠代码 1. manual //手工定义折叠 2. indent //用缩进表示折叠 3. expr //用表达式来定义折叠 4. syntax //用语法高亮来定义折叠 5. diff   //对没有更改的文本进行折叠 6. marker //用标志折叠 vim 配置文件分为全局配置文件和用户配置文件 1. 全局配置文件查找,在.vim 中输入

VIM设置代码折叠

VIM设置代码折叠 今天看了一下别人写的程序的源代码,发现是用vim写的,代码中有趣是用vim来折叠代码,一开始我以为是用插件的,后来上网查了查,得出以下使用方面的技巧. 1. 折叠方式 可用选项来设定折叠方式: 可在Vim 配置文件中设置 set fdm=XXX 可直接在文件中使用注释调用vim命令 /* vim: set fdm=XXX: */ 有6种方法来选定折叠: 1 2 3 4 5 6 . manual          手工定义折叠 . indent           更多的缩进表

IntelliJ IDEA 中使用region代码折叠

我使用的版本为2018.3,如下图: 选中要折叠的代码,使用快捷键:Ctrl+Alt+T,打开Surround With菜单,点击region...endregion Comments项(红框),如下图: idea会自动为选中的代码添加region,我们可以修改Description(折叠后的提示信息),如下图: 下图为折叠后的样子,折叠后会看到我修改的Description信息,点击前面的+号展开代码: 当然也可以手动添加region来进行代码折叠,代码如下: //region 折叠后的提示信

Eclipse保存时自动格式化代码

        使用Eclipse很长时间了,但是Eclipse有好多快捷好用的功能没有使用,现在在广州做项目,好多东西之前只是听过或者是简单的用,只是用到了皮毛,从身边人身上学到了一些东西,从eclipse软件使用开始分享.          eclipse保存时自动格式化代码,只需要在eclipse里设置一下就可以,eclipse自带这个功能,只是默认没有选中,要实现这个功能,只需要选上即可.具体的步骤:windows-->Preferences-->Java --> Editor-

代码折叠

升级到Xcode7后,会发现代码折叠功能不见了,这是怎么回事? 其实这个功能还在的,只是苹果默认把这个功能禁掉了:在Xcode菜单里选择Preference——Text Editing,你会发现里面有一个“code folding ribbon”,勾选它就能恢复代码折叠功能了. 然后通过菜单Editor——Code Folding,你就可以使用你需要的折叠功能. 相关快捷键: 局部折叠(折叠一个函数)                 :Command+Option+Left/Right 全局折叠

json 对c++类的序列化(自动生成代码)

[动机] 之前写网络协议的时候,使用的是google protobuf,protobuf不但在性能和扩展性上有很好的优势,protoc自动生成c++类代码的工具,这点确实给程序员带来了很多便利. 做后面一项目使用的json格式来传输,然后就萌生了实现像protoc这样的工具,根据json文件来生成c++类代码,并且生成序列化代码,这样在写网络的时候就无需把jsonvalue序列化散落在各处. [思路] 之前写object-c的时候,如果你要对类的序列化,你必须实现NSCoding协议(接口),