Mac的Terminal中无法使用mvim解决方案
Posted Modnar
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mac的Terminal中无法使用mvim解决方案相关的知识,希望对你有一定的参考价值。
对于每个人来说,都会有特别喜欢的编辑器。对于很多热爱Unix/Linux的人来说,Vim/vi肯定是很熟悉的“编辑利器”了。
当然,对于Mac用户来说,肯定也不乏对Vim狂热的人。庆幸的是,Vim对Mac用户提供了一个独立的应用程序MacVim。
作为一个Unix的衍生系统,macOS自然支持用户与OS通过Shell来交互,因此也就引入了要讨论的问题: 在Mac终端下,输入MacVim启动命令mvim却无法启动MacVim。
首先,考虑MacVim独立应用和Mac终端自带的Vim的区别:
1.MacVim作为Mac下的典型GUI Vim(gvim),能够提供更优秀的编辑界面,而不必拘束于Mac终端的配置文件(包括配色、窗口大小)
2.MacVim在使用时,是独立打开一个新的窗口,而不是像终端Vim一样,占用终端界面的窗口(当然,通过macOS的cmd+T快捷键也可创建一个新的Terminal标签页,切换过程只需Ctrl+Tab切换标签页,这样看起来似乎也让终端下Vim编辑文件显得更直观)
3.MacVim如果脱离终端来使用(每次都要点击MacVim应用来启动,并输入要编辑的文件的路径),将会变得失去其快捷性,尽管macOS可以让你把任何文件拖动到MacVim上来实现用MacVim对该文件进行编辑,但这似乎就在一定程度上违背了使用Vim的“初心”(我眼中的Vim,就是让人脱离鼠标,只靠键盘即可编辑一切)
因此,我们就需要让MacVim的启动速度如终端下Vim一样迅速便捷,又要让MacVim真正地启动自身的应用程序。这就是安装MacVim后,还会提供mvim命令的最好解释。
但是,在我的终端下,安装MacVim后,mvim命令却并不能发挥作用,具体表现如下:
1.将mvim拷贝一份到/usr/local/bin/目录下,重启bash,仍无法使用mvim,报错“Sorry, cannot find Vim executable.”
2.将mvim拷贝一份到/usr/bin/目录下(涉及到Apple在macOS更新中引入的RootLess控制机制,如何解除请查阅其他博客),无法使用mvim,报错相同
3.通过输入mvim可执行文件的全路径(/Applications/MacVim.app/Contents/bin/mvim)来执行mvim编辑文件,可行
当然,查阅了几篇如何解决1、2的报错的博客,但感觉众说纷纭...于是乎,便考虑自己来写一个类似解析命令的中间程序来帮助执行mvim命令
既然已经可以通过mvim全路径来执行,那么每次输入这个全路径自然是十分痛苦的,于是就考虑到用一个程序来帮助输入这些字符串。
于是,便可以写一个C程序来实现(暂且将这个程序叫做gvim):
于是,通过这段代码可以看到,在输入$ gvim file1.txt file2.txt ...之后,就能让Shell解析命令,传入到gvim程序中,gvim程序就会将这些字符串代表的文件“拼接”上mvim的全路径,再通过system函数来调用执行这条完整的命令: $ /Applications/MacVim.app/Contents/bin/mvim file1.txt file2.txt ...
这就是gvim的实现原理,也就是整个设计过程的思路。
但是!!!这个程序依旧是存在问题的,比如我在一个包含有20+个Java源文件的目录下,输入命令$gvim *.java 来对这些Java文件依次进行编辑,这时就会因为gvim.c中cmd的长度受限,此时Shell也只能反馈信息:"Abort trap: 6" (数组越界),这自然是肯定的,我的完整命令的长度超过了180的限定长度。
此时就回到了C/C++的经典问题,C中对于数组的内存分配是固定的(只指声明数组的方式来分配内存,不包括malloc、calloc函数),那么该如何分配给一个字符串适当的长度,能保证它既能包括我要输入的所有命令字符、又能不过多地消耗内存。
自然就想到了C++的String!(不要提Java...毕竟涉及到Shell了嘛,专业脸)
于是就有了gvim的C++版本:
这里,用到的就是std::string来实现字符串的构造,调用它的append方法来实现拼接,同时调用std::string.c_str()函数来实现std::string转换为const char *类型(因为system严格要求其传入参数为const char *类型),从而由于std::string的灵活性(长度变化由传入的字符串来决定),即可解决“输入的完整命令超级长”的问题。
至此,就可以编译生成这个可执行程序gvim了:
$ g++ gvim.cpp -o gvim
$ mv ./gvim /usr/local/bin/
重启Shell
至此,就可以用$ gvim 来代替 $ mvim 了。虽然并未从根本上解决掉那个问题,但终究是靠所学的知识达成了目标!
下面放出实验结果测试截图:
Okay,搞定!
希望此文能对那些配置mvim路径搞到头大的朋友,一个简单的解决思路。
纪念一下今天这个算是特殊的日子吧,感觉自己身上单身狗的芳香愈发浓郁......
========== 分割线 ==========
当然,通过Shell编程,可以更加简单地解决这个问题... 于是就有了方法3:
定义一个名字为"mvim"的可执行文件(Shell脚本),输入命令 “ /Applications/MacVim.app/Contents/bin/mvim $* ”。就像这样:
这个命令就是将所有参数(即$*)原封不动地传给前面的可执行程序(脚本),所以... 一句命令的事儿。
$ echo "/Applications/MacVim.app/Contents/bin/mvim $*" > mvim && mv mvim /usr/local/bin/
(到这儿,真的发现自己变化还是蛮大的,哈哈哈哈,当时的cpp竟然写得这么渣... 尽管现在还有好多不懂的东西,但慢慢积累吧,编辑记录都留着,见证成长[手动二哈])
当然,看到了评论区的命令别名,自然也是很好的解决办法,配置一下就ok,在此十分感谢。
希望还有方法建议的朋友评论区更正,感谢。
编辑于2018.5.20
第一次修改于2018.5.22
第二次修改于2019.3.1
以上是关于Mac的Terminal中无法使用mvim解决方案的主要内容,如果未能解决你的问题,请参考以下文章
Mac OS X 11中的/usr/bin 的“Operation not permitted”
Mac OS X 11中的/usr/bin 的“Operation not permitted”