需求:
前不久用codemirror做了一款在线IDE,业务那边用着反馈说很不顺手,提了一个优化需求,就是例如用if/else,while循环时,如果函数写的过长,就不知道有没有对齐,想要有像常用智能IDE中的引线辅助对齐功能:
现在的样子:没有竖线辅助对齐,If else写多了就容易对歪出错。
实现过程与踩坑记录:
- 进入codemirror官网查找对应功能,有没有现成的addon包可以用,一番苦找后,发现了这个addon与想象中的引线有点像,原来他们叫它rulers
- 引入后发现这个功能有点鸡肋,它需要你传入一个值,就是第几行需要有引线你就传第几行这个值,但我并能提前预见If else会出现在第几个column。这个时候的代码是这样的:
```javascript
data () {
return {
} }cmOptions: {
...
rulers: []
...
}
… for (let i = 1; i <= 10; i++) { this.cmOptions.rulers.push({ color: ‘#2e2e2e’, column: i * 4, lineStyle: ‘dashed’, width: 2 }) }
此时效果是只有在第4、8、12.。。等列数的地方有引线,而且非常僵硬,就算没有代码,也会有线。
- 继续查找官方api,想自己写一个类似的功能,至少在没有代码的地方不会有引线。于是又一番苦找,找到了这个api:doc.eachLine,思路就是,算出当前代码的最宽宽度,也就是最多有多少列,再根据缩进的个数去形成引线,这样不涉及到分析if/else这种语法,相对是快捷简单的实现。
此时的代码:需要监听代码每一次变动,分析得出当前最宽宽度。最后再监听最宽宽度变化时,引线跟着变化。
```javascript
watch: {
value () {
let lineMaxLength = 0
this.$nextTick(() => {
this.codemirror.getDoc().eachLine((line) => {
lineMaxLength = line.text.length > lineMaxLength ? line.text.length : lineMaxLength
})
this.maxLengthLine = lineMaxLength
})
},
maxLengthLine (val) {
this.cmOptions.rulers = []
for (let i = 1; i <= Math.floor(val/4); i++) {
this.cmOptions.rulers.push({ color: '#2e2e2e', column: i * 4, lineStyle: 'dashed', width: 2 })
}
}
}
...
...
- 最终效果
总结
codemirror有许多API,可以自己根据需要写出IDE想要的功能,就是查找起来会比较费时,需要掌握一些技巧,比如我就是搜vertical这个单词,逐步想到、找到的这个方法,其实还有待优化的地方,比如引线的长度应该至多与代码一样长,如果能分析语法去形成引线的话,当然就更智能好用了。