咱們都知道 Vim 和 Emacs 都是文本編輯器中的上古神器,你也許用 ctags,cscopes 配合 Vim 完成過大型 C 或者 C++ 的開發,你也許配合過其餘插件,完成過 JavaScript,python 代碼的開發,可是不多有人試過 iOS app 的開發吧,畢竟 iOS 的框架包含了不少東西,以及 Objective-C 天生很長的 API 名字,讓咱們沒辦法把此神器用起來,今天我就來給你們講下我是怎麼使用 Vim 開發 iOS App 的,固然 Emacs 也能夠php
使用 Vim 開發 iOS App 並非特殊的愛好,而是被 Xcode 8 活生生的逼的,剛開始更新了 Xcode 8 之後,Xcode 8 把第三方插件給屏蔽了,致使沒有 XVim 給我用了,沒有 XVim 之後,發現異常不順手,因而嘗試用了一段時間的 AppCode,不得不說 AppCode 是一個很是好的 IDE,可是他有個很大的缺點,那就是 Java,JetBrain 家的東西都很不錯,惟一缺點就是基於 Java,整個平臺都略慢,而後我在不斷的 google 過程當中,發現了有人竟不知何謂恐懼,居然使用 Vim 開發 iOS App,最後我也學會了這個新姿式 XDDDDpython
不過目前,只支持 Objective-C 代碼的開發,swift 的話,沒有解決工程文件自動補全的問題,由於目前你們使用的流行的 swift 自動補全工具 SourceKitten 並無支持 workspace 因此暫時還沒用起來git
以及,目前不支持調試,由於發現 Vim 對調試的支持確實好糟糕...github
工欲善其事,必先利其器,主角是 Vim 或者 Emacs,少了其餘配角和龍套們,也沒辦法正負恐懼,咱們來看看用到了些什麼東西,讓咱們的 Vim 成爲利器的,這裏只是點下他們的名,文章後面會把連接奉上objective-c
首先咱們來看主角隊的同窗們,他們是征服恐懼的主力swift
macOS,沒有神話,開發 iOS 仍是隻能在 Mac 上vim
支持 python 的 Vim,能夠用 Vim8 或是 neoVim 食用更佳,我就用的 neoVimbash
YCMD,其實他是 YouCompleteMe + YouCompelteMeDeamon 的合體,自動補全、定義跳轉等功能,就依賴他了app
接下來咱們來看看其餘龍套們框架
Vbundle,裝插件用的,沒他,龍套和主角都不用上場了
unite + unite-outline + unite-outline-objc,提供了方法導航
auto-pairs,自動補全右括號
ctrlp,文件搜索跳轉
Ag,字符串搜索工具
syntastic,語法檢查工具
vim-clang-format,代碼格式工具
恩,須要的東西大概就是這些了,Vim 的配置文件,我是基於很久之前 square 開源的 maximum-awesome 的,因此,配合這個食用風味更佳,個人 dot file 也放到了 github 上,歡迎你們 star
龍套們,基本均可以經過配置 vbundle 來完成安裝,以後只用配置對應的快捷鍵就行了,這裏的正題,要搞定難搞的主 YCMD
YCMD 的安裝很簡單,主要是須要必定的配置
首先在 vim 的配置文件中加入下面的內容,更新配置文件並執行 BundleInstall
命令,讓 Vbundle 把 YouCompleteMe 插件裝上
Plugin 'Valloric/YouCompleteMe'
而後到這個路徑 ~/.vim/bundle/YouCompleteMe
這裏是 YouCompleteMe 安裝的位置,在這裏須要編譯 YCM,一條命令就能夠搞定
./install.py --clang-completer --system-libclang
--clang-completer
告訴腳本咱們須要 clang 的支持,--system-libclang
告訴編譯腳本使用系統的 clang,由於以前 clang 升級 4.0 的時候,並無已經編譯好的包給我下載,因此這裏不用系統 clang 的話,編譯腳本會下載一個 clang 3.0,這樣就沒法支持 iOS 10.0 之後的 sdk 了,由於 iOS 10.0 之後的 sdk 爲了支持 swift 引入了一些 clang 3.0 不支持的新語法,因此這裏要加上 --system-libclang
而後等他編譯完成,這樣 YCMD 就配置好了,彷佛這裏看並非很難搞,其實難搞的是如何在 iOS 項目中配置好自動提示
這裏進入到了真正征服恐懼的地方了
曾經有人說過,編輯器再怎麼神器是沒辦法超過 IDE 的,由於 IDE 是經過編譯、解析整個項目的全部文件,來達到語法錯誤提示,自動補全,定義跳轉等高級功能的,而 YCMD 就是來彌補這一個差距的,YCMD 經過傳入完整的編譯參數,編譯須要提示的文件,來實現自動補全,這樣沒辦法超過 IDE 的部分就被抹平了
這裏咱們配置一個複雜的項目來練練手,首先 YCMD 是不可能經過 Xcode 的項目文件或是 workspace 文件獲取到編譯參數的,因此這一步須要手來,固然,未來能夠作成自動的,由於目前手動的作其實很方便,因此如今尚未作成自動的
首先,YCMD 是經過每一個項目路徑下的 .ycm_extra_conf.py
腳本文件來獲取編譯參數的,這個腳本文件中有一個叫作 FlagsForFile
的函數,咱們經過這個函數返回某一個特定文件須要的編譯參數,通常狀況下大部分文件的編譯參數是同樣的,咱們來看一個配置的列子
import os import ycm_core flags = [ '-resource-dir', '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0', '-x objective-c', '-arch armv7', '-fmessage-length=0', # '-fmodules', # '-gmodules', '-fdiagnostics-show-note-include-stack', '-fmacro-backtrace-limit=0', '-D__arm__=1', '-D__IPHONE_OS_VERSION_MIN_REQUIRED=80000', '-std=gnu99', '-fobjc-arc', '-Wnon-modular-include-in-framework-module', '-Werror=non-modular-include-in-framework-module', '-Wno-trigraphs', '-fpascal-strings', '-Os', '-fno-common', '-Wno-missing-field-initializers', '-Wno-missing-prototypes', '-Werror=return-type', '-Wunreachable-code', '-Wno-implicit-atomic-properties', '-Werror=deprecated-objc-isa-usage', '-Werror=objc-root-class', '-Wno-arc-repeated-use-of-weak', '-Wduplicate-method-match', '-Wno-missing-braces', '-Wparentheses', '-Wswitch', '-Wunused-function', '-Wno-unused-label', '-Wno-unused-parameter', '-Wunused-variable', '-Wunused-value', '-Wempty-body', '-Wconditional-uninitialized', '-Wno-unknown-pragmas', '-Wno-shadow', '-Wno-four-char-constants', '-Wno-conversion', '-Wconstant-conversion', '-Wint-conversion', '-Wbool-conversion', '-Wenum-conversion', '-Wshorten-64-to-32', '-Wpointer-sign', '-Wno-newline-eof', '-Wno-selector', '-Wno-strict-selector-match', '-Wundeclared-selector', '-Wno-deprecated-implementations', '-DOBJC_OLD_DISPATCH_PROTOTYPES=0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk', '-fstrict-aliasing', '-Wprotocol', '-Wdeprecated-declarations', '-miphoneos-version-min=8.0', '-g', '-Wno-sign-conversion', '-Wno-infinite-recursion', '-fembed-bitcode-marker', '-I/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform', '-I/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include', '-I/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks', '-I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0/include', '-F/Users/apple/Documents/Developer/CloudLifeWorkspace/iOS/Develop/Project_iOS/project', '-MMD', '-MT', '-MF', ] SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ] HEADER_EXTENSIONS = [ '.hpp', '.hxx', '.hh', '.h' ] def FlagsForFile( filename, **kwargs ): staticFlags = flags return { 'flags': staticFlags, 'do_cache': True }
這裏上面的代碼能夠看成 .ycmd_extra_conf
文件的一個最小模板,也就是若是咱們的項目裏面沒有子目錄,沒有第三方庫,那麼使用這個已經能夠爲 iOS 項目提供自動提示了
顫抖吧凡人,如此這般的編譯條件,須要你可以把 Xcode 項目配置中的編譯參數完徹底全翻譯出來才行,可是我也是凡人,因此這個不是我寫的,而是有方法生成的,方法以下
把須要增長自動提示的項目用 Xcode 打開,而後編譯,而後以下圖所示,找到編譯信息而後找到項目中的一個文件,注意不要是 Pod 中的文件,最右邊,有個三條橫線的按鈕,點開他,沒錯,你看到了完整的編譯參數,下圖中 EXPORT PATH =....
下面的全部內容就是完整的編譯參數
Report View
戳這個按鈕
咱們要的編譯信息
右鍵,copy,找到你熟悉的記事本,參數都是空格分隔的,因此,這裏咱們把它轉換成上面代碼中的形式,並把不須要的去掉,好比這裏我註釋了 -fmodules
和 -gmodules
由於這樣編譯沒辦法使用 module
把這些加入到配置文件中後,再打開 Vim 你就會發現自動提示變得很是好用了,不過這裏還會有一個問題,若是編譯的時候,有沒法找到 UIKit
,這是由於 YCMD 默認引入了 macOS SDK 的路徑,致使了編譯時 clang 認爲咱們編譯目標是 macOS,因此以下圖須要修改 ~/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/completers/cpp/flags.py
文件,去掉默認引入 macOS sdk 的編譯參數,這樣就行了
至此,最主要的問題已經被咱們解決了,接下來看下效果如何
首先是自動提示
查找文件
方法名稱大綱
搜索字符串
語法檢查
這麼作天然不是爲了花樣炫技,更多的是爲了探索 Vim 的使用,以及更多瞭解 Xcode 項目
完整的 Vim 環境,寫代碼不再用碰鼠標了
Vim 插件 + 不滿的地方本身動手豐衣足食
快速,跟 Vim 比速度,笑話
方便快接的字符串搜索,替換操做
學了點 Python
附贈一個 C/C++ 的開發環境
雖然目前已經能夠達到寫代碼的程度了,可是仍是有不少問題,以下:
沒辦法 debug
不支持 Xcode 中的 group 展現
頭文件的提示有問題
不能使用 @import
的導入,會報語法錯誤
xib,storyboard 天然是不行的,個人作法是 Xcode 裏面拖 UI + 關聯 Outlet + Debug,Vim 中作大量的代碼編輯操做
[]
方括號的匹配沒有 Xcode 那麼智能
delegate 或是全局的自動提示,須要使用 ctrl + 空格打開,而且有時候會有點慢
delegate 的自動提示有時候須要輸入前面半部分的方法名纔會有,好比上面截圖的 tableView,須要先輸入 - (void)tableView:(UITableView *)tableView
再使用 ctrl + 空格纔會有很是好的自動提示,固然輸入前面這部分也會有必定的提示,總體上看能接受
上面的問題都是一直以來我沒有解決的問題,你們要是發現有破解的方法,歡迎聯繫
折騰這麼多,相信你們已經能夠用 Vim 敲 iOS 的代碼了,雖然雖然當初開始折騰的時候,踩了不少坑,好比 clang 3 升級 clang 4 後,原來的配置都不能用了,可是收穫挺多的也並非這麼一篇文章可以說完的,除了 Vim 你們也能夠試試 Emacs 下的配置,我用的 Spacemacs,添加了 ycmd 的 layer,配置後也有了相同的效果
也歡迎你們丟磚
YouCompleteMe: 自動補全插件
Vbundle: 插件管理插件
Unite: 一個通用的顯示插件,能夠用來顯示各類東西,好比文件列表,buffer 列表,outline
Unite-outline: Unite 插件的 outline 插件
Unite-outline-objc: Unite-outline 插件的 Objective-C 插件
auto-pairs: 自動補全括號的插件
ctrlp: 文件查找插件
Ag: 字符串查找插件
syntastic: 語法檢查插件
vim-clang-format: clang format 格式化插件
VimAwesome: 方便的 Vim 插件導航網站
maximum-awesome: 一個比較有名的 Vim 配置,包括了上面的 Vbundle,Ag,ctrlp,syntastic 等插件,以及一些很方便的配置,個人配置文件是基於這個配置的,使用前先安裝這個
個人配置文件: 個人配置文件,除了上文寫的內容,還加了些 php,python,js 等開發配置,以及一些本身以爲用起來方便的配置