• 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

  • 相关阅读:
    有关怎样入门ACM
    在线安装eclipse中html/jsp/xml editor插件(很可靠)
    如何才干高速成为优秀的程序猿
    JavaScript必知的特性(继承)
    Maven构建真正的J2EE项目
    HLJU 1223: 寻找区间和 (交替推进法)
    重要经验五:block作为属性的注意事项
    Android Studio第一次启动的Fetching android sdk component information的问题
    树莓派学习笔记——apt方式安装opencv
    大型项目开发: 隔离 (《大规模C++程序设计》书摘)
  • 原文地址:https://www.cnblogs.com/stevenshen123/p/9065259.html
Copyright © 2020-2023  润新知