Skip to content

2010年02月5日

在StyledTextCtrl中自定义代码折叠

代码折叠功能是一个完善的编辑器不可缺少的功能,在StyledTextCtrl中可以自定义语法高亮,当然也可以自定义代码折叠(关于自定义语法高亮,大家爱可以读读limodou大侠的《StyledTextCtrl语法高亮使用的探讨》一文)。
StyledTextCtrl中的代码折叠的基础是每行的FoldLevel值,FoldLevel值的大小不同,就形成了不同的代码块,例如:

这样的折叠效果,每行的FoldLevel为:

第一列是行(从0开始是第一行),第二列是FoldLevel,第三列是FoldLevel原始值;第二列的FoldLevel由第三列FoldLevel原始值解码出来。
代码被设计成基于大括号折叠,对比两个图,可以找出规律:最外层的“{”FoldLevel是1024,第二个“{”是1025,第三个“{”是1026;它们的FoldLevel都大于8192(wx.stc.STC_FOLDLEVELHEADERFLAG),这表示了他们是折叠的开始。
剩下的行,凡属于代码块的行,都会比折叠的开始行要小。
控件就会根据每行的FoldLevel值不一样,产生了折叠效果。

这里有个设置每行FoldLevel值的代码片段,供产考:

def MakeFoldLevel(self, begin = 0):
	beginPosition = 0

	endPosition = self.editor.GetTextLength()

	currentLine  = self.editor.LineFromPosition(beginPosition)
	currentLineLevel = self.editor.GetFoldLevel(currentLine) & wx.stc.STC_FOLDLEVELNUMBERMASK
	prevLineLevel = currentLineLevel

	i = 0
	while beginPosition + i < endPosition:
		pos = beginPosition + i
		currentChr = chr(self.editor.GetCharAt(pos))

		if self.editor.GetStyleAt(pos) == styleIndex['bracket']:
			if currentChr == '{':
				currentLineLevel += 1
			elif currentChr == '}':
				currentLineLevel -= 1

		if (currentChr=="\n") or (currentChr=="\r" and chr(self.editor.GetCharAt(pos+1))!="\n"):

			level = prevLineLevel

			if currentLineLevel > prevLineLevel:
				level |= wx.stc.STC_FOLDLEVELHEADERFLAG

			if level != self.editor.GetFoldLevel(currentLine):
				self.editor.SetFoldLevel(currentLine, level)

			currentLine += 1
			prevLineLevel = currentLineLevel

		i += 1

	if currentLineLevel<>prevLineLevel:
		self.editor.SetFoldLevel(currentLine, prevLineLevel)
	else:
		self.editor.SetFoldLevel(currentLine, currentLineLevel)

这不是教程,只是对实现思路的探讨,更多内容请参考官方文档,谢谢关注 ^_^

Read more from Python, 笔记

Share your thoughts, post a comment.

(required)
(required)

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments