gyn

Win32下的Perl,无用的select,停滞的Tk,结束吧....

类Emacs窗体分割之我见

其实也并非 Emacs 专有,像 Vim 或者 UE 也有类似的功能,只是我用 Emacs 比较多,所以才取了这个题目。总之,就是将在编辑的一个文本框分割为垂直或者水平的两个相同大小的文本,对于同一个编辑目标,两者保持相同的内容变更,但两者又可分别显示不同的编辑对象,被分割出来的两个文本框又可自行再次分割,以此类推。如果看的迷糊的,自己试试 Emacs 去,“ Control x 2 3 )”就行。

这么做的好处在于可以同时观察到两个相关的代码段,有助于查找需要的信息,或者其中一个编辑另一个执行某个如 tclsh 的命令,等等。差不多就是一个多任务的形式,思维比较活跃的人多是喜欢这样开好几个窗口干活。

这个看似简单易用的玩意儿,实现起来却有点让人无从下手。首先,要让两个同编辑目标的文本框保持同步更新;第二,同一个文本框中切换不同编辑对象时,需要保证如语法渲染之类的操作不影响切换速度;第三,保证分割出来的文本框不会改变父窗体的大小。也许还有别的问题,但这三个是让我有点茫然的东西。

经过一番思量,对于第一个问题,应该可以用 rename 注入代码完成。这在我之前写的文章里有很多涉及,这里就具体不讲。只是需要判断一下两个文本框的编辑对象是否一致。如此一来,对于第二个问题,则需要在每次切换的时候将涉及到渲染或者计算的部分以一定结构的数据形式将结果存储起来以备后用,比如将用于作色渲染的 tag 标记都 dump 出来,还有复制内容,当前插入点等等。

不过,在这里我采用了另一种更加优雅的方式,其实是使用了在 Tk8.5 中新加入的 text 组件命令: peer ,在 actovetcl demo 中也可以看到相关的例子。就是对于一个已建的 text 组件,通过 peer 命令生成它的镜像对象,这两个对象是完全相同的,对任一个的才做都会影响其他对象的变现。事实上,对于一个新建的文本编辑对象,我都首先生成了一个不被 geometry text 对象,用术语说就是 buffer ,再针对这个 buffer peer 出所有需要显示的文本框窗体。那么对于第二个问题,就不是某个 text 组件中内容之间的切换了,而是不同 text 组件之间的切换,可以通过 forget 来完成。这么做的好处在于,我肯本不用考虑切换时状态存储,而且 peer 可以更好地保证编辑对象的一致性要求。

而第三个问题的解决让我对 geometry 中的 place 命令有了全新的认识。众所周知, geometry 的三种方法中,最被广泛使用的是 pack ,其次是 grid ,最后才是 place 。无论那本介绍 Tk 的书籍,都是按照这个顺寻来编写的。也许是应为 pack 的命令最短,也更通俗易懂一些。但在这里,我不得不使用 place 。对于一个需要被分割的文本框,以下的代码很难控制父窗体的大小。

package require Tk

text .t1

text .t2

pack .t1 –fill both –expand 1

pack forget .t1

pack .t1 .t2 -side left –fill both –expand 1

事实上,这么做的结果是使父窗体加宽了一倍。即使你小心地设定了 text 组件的 width ,一旦 fill 开来就面目全非了。在这里只能使用 place ,结合相对起点与相对长宽,精确设定分割窗体大小。以下是一个实现类以上所讲到和没讲到的功能的完整 demo ,有兴趣的可以看看。其中还包含了切换和关闭 buffer 的快捷键。
split.tcl文件下载

posted on 2009-09-29 19:42 gyn_tadao 阅读(894) 评论(2)  编辑 收藏 引用 所属分类: TclTk

评论

# re: 类Emacs窗体分割之我见 2009-10-14 11:49 淘宝导购

不错哦233  回复  更多评论   

# re: 类Emacs窗体分割之我见 2009-10-26 17:09 凡客诚品断码

包含了切换和关闭 buffer 的快捷键。
这个源码还不错,谢谢了  回复  更多评论   

只有注册用户登录后才能发表评论。
<2009年9月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

导航

统计

常用链接

留言簿(14)

随笔分类(126)

随笔档案(108)

相册

搜索

最新评论

阅读排行榜

评论排行榜