2020年5月24日 星期日

Windows 下 YouCompleteMe 安裝步驟

markdown [YouCompleteMe](https://github.com/ycm-core/YouCompleteMe) 是一個非常強大的 vim 套件,在各個工作環境中也安裝好幾次了,不過安裝過程有點複雜,每次都要重新看一次文件才知道要怎麼裝,這裡寫一下簡略的步驟,讓以後要在新環境安裝時可以很快的喚起記憶。 使用的平台是 Windows,搭配的 vim 也是 Windows 版的 gvim,因為工作環境都是在 Windows 中。 ## 第一步:安裝 YouCompleteMe 編譯所需套件 因為 YouCompleteMe 沒有提供預先編譯好的執行檔,需要下載它的程式碼在你本機電腦編譯,所以要先安裝好編譯所需的套件。安裝步驟以及所需套件在 YouCompleteMe 的 [Github](https://github.com/ycm-core/YouCompleteMe#windows) 官網就有說明清楚。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3DrprbjbCK_VlRykmsvglAJftxzUgoE4yBreR7t-zuYo_b6LkJyvyxPbVDZJj0H0hXEhMBg0nu34_GULe9A8PXv_TiKuFlflQbFsj1tDmx_pLM5n7TiGnl8VHc2RCx9rzK0tBEd4KfXNk/s1600/Image+2.png) 安裝 python 時要注意,如果安裝的 gvim 是 32 位元的,python 也要安裝 32 位元的版本,否則 gvim 無法載入 python dll。當然 gvim 本身也要安裝支援 python 的版本,可以用 `gvim --version` 來檢查,是否有 +python/dyn +python3/dyn 的 feature。 想知道 gvim 有沒有成功載入 python dll,可以用 command `:py3 pass` 來檢查,如果顯示無法載入,可能是因為 gvim 找不到 python dll。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjY8VOvSd8mja1IExn90m3GCXGCc-ID_BQ_AjfOmRUat6lUlXjUyOAnthDh2W0OJupxOhe3eRdeH0JcjhYJSTGb-BY4tsTxmWnP4aj80yX-dSHBnxt1_LkYLzlVUUMWJ60DJx-FsoyLwvb3/s1600/Image+1.png) 這時可以用 pythonthreedll 跟 pythonthreehome 來設定 python dll 位置讓 gvim 可以找到。 ## 第二步:安裝 Vundle [Vundle](https://github.com/VundleVim/Vundle.Vim) 是一個 vim 的套件管理員,需將 Vundle 安裝好之後,再用 Vundle 把 YouCompleteMe 原始碼抓下來。 安裝步驟就照著 [Vundle 官網](https://github.com/VundleVim/Vundle.vim/wiki/Vundle-for-Windows) 的說明,其實主要就是將 Vundle.vim 用 `git clone` 到 vim 的設定檔目錄里。 當然,跟 linux 上的 ~/.vim 不一樣,Windows 的 gvim 設定檔目錄通常是在
C:\Program Files (x86)\Vim\vimfiles
官網給的範例是用 .vim 路徑,下載時要注意一下路徑的不同。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik2L9CBR_q7InxSZrAEs04lufKg4FyaF3WjxnU2-_T028Ph1PH30SINw_bF_dWkeo0AJoi3KzliXaRoC7MLPgzjnuz_YyYsmhcbr7PG8-FGJNLlmbvd3uegPzTIKdHBeafLtNzZ96rEfVY/s1600/Image+3.png) ## 第三步:下載 YouCompleteMe Vundle.vim 裝好後就是照著[官網範例](https://github.com/VundleVim/Vundle.Vim#quick-start)將你想裝的 Plugin,包含 YouCompleteMe 寫到 _vimrc 設定檔中,然後執行 `:PluginInstall`,接著就等 Vundle 將 YouCompleteMe 原始碼抓下來了。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinAvtAUHOBFwAYhvkLfdDlxv9HWboT_Ex7lBZJn7UDIuPsb9RKPgiqP0WaBSrsw0QwAK3hAWCRugHNoevAOq6vZNj2qKOrhttjGJoD0FqvAozFADFWK_pgXd2oqqfHdFzabJMEUvIcG5Nz/s1600/Image+6.png) 安裝過程中我出現了無法存取 temp 資料夾下檔案的問題,結果是因為權限不足,用管理者權限開啟 gvim 後執行 `:PluginInstall` 就可以了。 ## 第四步:編譯 YouCompleteMe 原始碼 因為在第一步已經將 YouCompleteMe 編譯所需套件安裝好,所以 Vundle 將 YouCompleteMe 原始碼抓下來後,在 YouCompleteMe 目錄下執行 `install.py --all`,就會開始編譯 YouCompleteMe 了,--all 選項是將 YouCompleteMe 對各種語言的自動完成都打開,例如 C/C++ 或 java 等等。 當然,不一定你套件裝完然後 `install.py --all` 跑下去就可以直接開始編譯沒問題了,例如我裝的最新版 cmake 要搭配 Visual Studio 2019 的 build tool,不能用 YouCompleteMe 官網上寫的 Visual Studio 2017,不過如果有問題,通常都會顯示錯誤訊息,這時就只能照著錯誤訊息的提示一步一步解決,搭建好你的編譯環境。 等到 YouCompleteMe 編譯完成,沒意外的話,就可以開始使用,享受它強大的自動補完功能了。
## 一些常見問題 ### Unable to detect a .tern-project file vim 開起來時可能會發現顯示 Unable to detect a .tern-project file 的 warning,只要照[官網](https://github.com/ycm-core/YouCompleteMe#javascript-and-typescript-semantic-completion)的指示,將 `third_party/ycmd/third_party/tern_runtime/node_module` folder 刪除即可 ### 安裝 NERDTree 後發現 vim 結束時 YCM daemon 沒有跟著結束 YCM daemon 基本上就是一個 python process,沒有正常跟著 vim 結束的話,系統中會看到很多孤立的 python.exe 占用系統資源,經過 debug 發現 YCM 註冊一個 handler 到 vim 的 VimLeave 中,當 VimLeave trigger 時執行該 event 然後結束 YCM。但是安裝 NERDTree 後會發現 VimLeave 沒有被呼叫了。 確切來說是 NERDTree README 的一個 autocmd 造成 VimLeave 失效,這個 autocmd 會讓 NERDTree 是最後一個 vim 視窗時結束 vim,我想應該每個裝 NERDTree 的人都會用才對。
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
在 github 有人提出 [issue](https://github.com/preservim/nerdtree/issues/1108),只要在加個 nested 就可以解了。
autocmd bufenter * nested 
    \ if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif

2020年5月3日 星期日

[Android] system tracing

markdown systrace 是一個用來量測 Android 系統層級執行時間的 command line tool,位置在 android-sdk/platform-tools/systrace/systrace.py,是一個 python script。它的一些參數可以看[官方文件](https://developer.android.com/topic/performance/tracing/command-line)的說明。 在講 systrace 的用法之前,先來講一下為什麼它可以收集 Android 系統的執行時間,Android 本身會在很多重要的函數前後插入 Label,用這個資訊讓 systrace 可以知道某個函數執行了多久。所謂插入 Label,其實就是呼叫 [TraceCompat](https://developer.android.com/reference/android/support/v4/os/TraceCompat) 的 beginSection 和 endSection。例如在 RecyclerView 的 onLayout 就有插入 Label。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibRjV9ccicC5xhih9wBTdxMnDKqq73mg38BG6AOVv5Mrlc6bE4JCggMTFcgaCnHfVl8JMiVpUWt_grolqxF3dnXxctDSb3isDC12L-ZNN4gBzsD1ChuN2bwz-p5A27z1Oe-586ff037nw3/s1600/Image+2.png) 這樣的 Label 被插入到 Android 系統的各個關鍵 call path 中,讓你可以知道你的 app 在這些系統函數到底花了多久時間。 執行 systrace 時會喂給它時間參數,表示你希望它收集多久的資料,然後是各個模組名稱,表示你希望它收集哪些模組的資料。還有你自己 app 的 package name,這樣 systrace 也會抓你自己在 app code 中插入的 Label,例如下面是我用來 debug UI 卡頓時常用的命令。
systrace.py -t 3 sched gfx view -a myapp.package.name --no-compress
systrace 執行完之後,就會在目錄中產生一個 trace.html 檔案,這個檔案可以用 chrome 開啟,用圖形化的界面顯示執行時間,如下圖,你可以用 WASD 按鍵做移動還有放大跟縮小 timeline。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnOkhF7X1mkYZ5Cr5Qw8UxuPo3cp6d4PT48hyphenhyphenz9odjEj7penLMDnCukpVxoAJgYG182-Y03XD7OlUu5ExZfdivVGJz-6rlyC94E2fVkFyKVZepgiiZId_fJQ4kxJczHO4KVF4_Rul5Wv0u/s1600/Image+1.png) 跟 method trace 不同,systrace 只記錄某些關鍵 call path 的執行時間,不過這也正好是他的優點,因為 method trace 記錄的 method 太多,除非有某個函數真的明顯跟其他函數比起來花了太多時間,不然在調查效能瓶頸時很容易被淹沒在函數海中,找不到該優化的地方。用 systrace 可以先從大方向找出在哪些系統函式比較耗時,接著再用 method trace 做深入追查,這樣會比較有效率。 --- * [Overview of system tracing](https://developer.android.com/topic/performance/tracing/)