顯示具有 vim 標籤的文章。 顯示所有文章
顯示具有 vim 標籤的文章。 顯示所有文章

2025/06/02

Neovim Copilot Chat Plugin

Github Copilot 已經是我工作上的好幫手,它的好處是你付一次月租他可以支援所有你有支援的軟體,我安裝在 Jetbrains 全套、vscode、neovim,一魚多吃相當方便,這邊介紹一下 vim/neovim 用來跟 copilot 對話的好用插件 CopilotChat.nvim,當然你要使用之前必須先有 copilot 帳號,以及安裝開通 copilot.vim。

網站中有許多 plugin 安裝的方式,選自己常用的安裝即可,在你的 vim/neovim 配置檔案要加入啟動的語法:

lua << EOF
    require("CopilotChat").setup { }
EOF

" 用 cc 叫出視窗
nnoremap <silent> cc :CopilotChatToggle<CR>

我習慣是盡量不太修改插件預設值,避免有轉換環境的痛苦,套用 cc 叫出視窗是我針對 CopilotChat 唯一的設定了,我們用撰寫一個 docker-compose.yml 當作範例。

nvim docker-compose.yml 建立一個檔案,進入 vim/neovim 按下 cc,可以看到 CopilotChat 視窗在左邊出現。

以下是常用的快捷鍵以及指令:

插入模式 普通模式 功能說明
<Tab> - 觸發或接受補全選單(tokens 自動完成)
<C-c> q 關閉聊天視窗
<C-l> <C-l> 重設並清空聊天視窗
<C-s> <CR> 提交當前的提示內容
- grr 切換目前游標所在行是否為「固定提示」
- grx 清除所有「固定提示」
<C-y> <C-y> 接受最近的一個差異(diff)
- gj 跳轉到最近差異的區塊
- gqa 將所有回覆加入 quickfix 清單
- gqd 將所有差異加入 quickfix 清單
- gy 將最近的差異複製(yank)到暫存器
- gd 顯示原始內容與最近差異的比對
- gi 顯示目前聊天的資訊
- gc 顯示目前聊天的上下文
- gh 顯示說明訊息
指令 說明
:CopilotChat <輸入內容>? 開啟聊天視窗,並可選擇性地輸入問題或指令
:CopilotChatOpen 開啟聊天視窗
:CopilotChatClose 關閉聊天視窗
:CopilotChatToggle 切換聊天視窗(開啟與關閉間切換)
:CopilotChatStop 停止目前的輸出(中斷正在生成的內容)
:CopilotChatReset 重設聊天視窗(清除目前對話)
:CopilotChatSave <名稱>? 儲存聊天記錄,可選擇性指定一個名稱
:CopilotChatLoad <名稱>? 載入先前儲存的聊天記錄
:CopilotChatPrompts 查看並選擇提示範本(例如:解釋代碼、重構等用途)
:CopilotChatModels 查看並選擇可使用的 AI 模型
:CopilotChatAgents 查看並選擇可用的 AI 助手代理(不同風格或角色)
:CopilotChat<PromptName> 使用特定提示範本開啟對話(例如 :CopilotChatExplain)

現在位於左邊的 CC 視窗,輸入寫一份 docker-compose.yml,需要安裝 nginx 以及 php-fpm,先按 esc 回到 visual mode 以後再按下 enter。

我們可以看到他幫我們產生了許多內容,下面包含了基礎的 nginx 配置,更下方還有測試用的 php 程式碼,但我需要的只有 docker-compose 的部分,所以我將 cursor 移到我需要的區塊,然後按下 ctrl + y,此時他便將該區塊的程式碼移到了右邊去。

我接著輸入 prompt,現在的 docker-compose 不需要使用 version,他會依照上文幫我重產內容。

我們可以使用 gd 快速看出差異。

按下 q 回來以後,一樣使用 ctrl + y 將改變套用,這樣就可以套用新的格式,假設你已經脫離上下文,需要透過 cc 給你的檔案建議呢,這時就要用 vim/neovim 的選取功能,將需要他幫忙的地方選取起來,再去問一下 cc。

一樣用 ctrl + y 套用結果,如果你是要他參考整個文件就得使用全選了,另外一種方式是在命令列輸入 :CopilotChat 將 nginx 改為 ubuntu 版本 #buffer,這樣他就會把該檔案的內容當作緩衝使用,我自己是覺得用選的比較快。

另外一個主動參考整個文件的方法就是在第一次打開視窗問問題時,加上 #buffer,例如:

#buffer 將 $name 取代為 $userName

這樣他便會去直接參考整個檔案。

當我們使用 :CopilotChatModels 時,他會列出所有你可以使用的 model,可以記一下編號,移動到最下面後可以填入該編號,便可以切換模型。

但這個變動只有在這次有效,要永久使用該模型可以設定 config。

lua << EOF
require("CopilotChat").setup {
    model = 'claude-3.7-sonnet'
}
EOF

2025/04/02

Neovim Installation

neovim 是我即便是在 windows 下也會開來使用的 command line editor,來 memo 一下 Windows 跟 Linux 怎麼安裝。

Windows

我在 Windows 上都是使用 scoop 來管理套件,所以 neovim 也是用 scoop 來安裝,這樣好處是我用 scoop update 時都可以保持拿到最新的 neovim。

scoop install neovim

powershell 可以執行指令安裝 vim-plug。

iwr -useb https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim | ni $HOME\AppData\Local\nvim\autoload\plug.vim -Force

接下來就是配置你的個人檔案,位置在 C:\Users\你的使用者名稱\AppData\Local\nvim\init.vim,可以使用任何編輯軟體包括 neovim 開啟他,把 config 都配好以後,執行 neovim,首次執行會有很多錯誤是正常的,因為你的 plugin 並沒有真的安裝,開啟後執行 :PluginInstall,關閉再開啟 neovim 應該就正常了。

Linux

Linux 的部分有兩種方法,一個是透過你自己的 OS 去找最新的 repo 安裝,另一個是可以去 https://github.com/neovim/neovim/releases/,neovim 的 github 官網找最新版本的 appimage 檔案,只要你的 OS 有 FUSE 就可以直接使用,以 ubuntu 22 為例,此文章撰寫時最新的穩定版本是 NVIM v0.11.0。

curl -LO https://github.com/neovim/neovim/releases/download/v0.11.0/nvim-linux-x86_64.appimage
chmod +x nvim-linux-x86_64.appimage
sudo mv nvim-linux-x86_64.appimage /usr/local/bin/nvim

執行完這段就有 nvim 可以執行了,接著裝套件。

sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs \
       https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'

mkdir -p ~/.config/nvim
touch ~/.config/nvim/init.vim
nvim ~/.config/nvim/init.vim

接著就跟 Windows 一樣安裝套件後就可以用了,之後要更新 neovim 版本只要抓最新版本的 appimage 替換即可。

2016/05/05

vim auto install

我之前有把 vim 的安裝過程寫成 script,放在 dropbox 上,但前天遇到 dropbox 連不上而必須建立環境的窘境,所以還是 blog 放一篇比較穩當。

vim_centos_dispatch.sh

sudo localedef -i zh_TW -c -f UTF-8 zh_TW.UTF-8
sudo yum -y install vim
sudo yum -y install git
sudo mkdir -p ~/.vim/autoload
sudo mkdir -p ~/.vim/bundle
sudo curl -o ~/.vimrc https://dl.dropboxusercontent.com/u/15447570/vim/config.txt
sudo curl -o ~/.vim/bundle/install.sh https://dl.dropboxusercontent.com/u/15447570/vim/install.sh
sudo curl -o ~/.vim/bundle/update.sh https://dl.dropboxusercontent.com/u/15447570/vim/update.sh
sudo curl -o ~/.vim/autoload/pathogen.vim https://raw.githubusercontent.com/tpope/vim-pathogen/master/autoload/pathogen.vim
cd ~/.vim/bundle
sudo sh install.sh
cd -

vim_ubuntu_dispatch.sh

sudo locale-gen --lang zh_TW.UTF-8
sudo aptitude -y install vim
sudo aptitude -y install git
sudo mkdir -p ~/.vim/autoload
sudo mkdir -p ~/.vim/bundle
sudo curl -o ~/.vimrc https://dl.dropboxusercontent.com/u/15447570/vim/config.txt
sudo curl -o ~/.vim/bundle/install.sh https://dl.dropboxusercontent.com/u/15447570/vim/install.sh
sudo curl -o ~/.vim/bundle/update.sh https://dl.dropboxusercontent.com/u/15447570/vim/update.sh
sudo curl -o ~/.vim/autoload/pathogen.vim https://raw.githubusercontent.com/tpope/vim-pathogen/master/autoload/pathogen.vim
cd ~/.vim/bundle
sudo sh install.sh
cd -

.vimrc

execute pathogen#infect()
syntax on
filetype plugin indent on
:filetype plugin on
language messages zh_TW.utf-8
autocmd FileType php set omnifunc=phpcomplete#CompletePHP
colorscheme jellybeans

set autoindent
set backspace=indent,eol,start
set clipboard=unnamed
set cursorline
set encoding=utf-8
set expandtab
set fileencoding=utf-8
set fileencodings=utf-8,big5,euc-jp,gbk,euc-kr,utf-bom,iso8859-1
set foldcolumn=1
set guifont=Consolas:h12
set laststatus=2
set nobackup
set noundofile
set nowritebackup
set number
set shellslash
set shiftwidth=4
set t_Co=256
set tabstop=4
set tenc=utf-8
set winheight=5
set winminheight=5
set winheight=999

let g:EasyMotion_leader_key = '<Leader>'
let g:ctrlp_working_path_mode = 0
let g:syntastic_auto_jump = 1
let g:syntastic_php_checkers = ['php']
let g:airline_powerline_fonts = 1
let g:vim_php_refactoring_auto_validate_sg = 1
let g:vim_php_refactoring_auto_validate_rename = 1
let g:vim_php_refactoring_auto_validate_visibility = 1
let g:phpunit_bin = '/root/.composer/vendor/bin/phpunit'

:map <C-t> :tabnew<CR>
:map <C-l> :tabnext<CR>
:map <C-h> :tabprevious<CR>
:map <F2> :NERDTreeToggle<CR>
:map <F3> :Flisttoggle<CR>

_vimrc

set nocompatible
source $VIMRUNTIME/vimrc_example.vim
source $VIMRUNTIME/mswin.vim
behave mswin

execute pathogen#infect()
syntax on
filetype plugin indent on
:filetype plugin on
source $VIMRUNTIME/delmenu.vim
language messages zh_TW.utf-8
autocmd FileType php set omnifunc=phpcomplete#CompletePHP
colorscheme jellybeans

set autoindent
set cursorline
set encoding=utf-8
set expandtab
set fileencoding=utf-8
set fileencodings=utf-8,big5,euc-jp,gbk,euc-kr,utf-bom,iso8859-1
set foldcolumn=1
set guifont=Consolas:h12
set laststatus=2
set noundofile
set nowritebackup
set nobackup
set number
set shellslash
set shiftwidth=4
set tabstop=4
set tenc=utf-8
set winheight=5
set winminheight=5
set winheight=999

let g:EasyMotion_leader_key = '<Leader>'
let g:airline_powerline_fonts = 1
let g:ctrlp_working_path_mode = 0
let g:syntastic_auto_jump = 1
let g:syntastic_php_checkers = ['php']
let g:syntastic_javascript_checkers = ['jshint']
let g:vim_php_refactoring_auto_validate_sg = 1
let g:vim_php_refactoring_auto_validate_rename = 1
let g:vim_php_refactoring_auto_validate_visibility = 1
let g:phpunit_bin = 'C:/Users/chan/AppData/Roaming/Composer/vendor/bin/phpunit'

:map <C-t> :tabnew<CR>
:map <C-l> :tabnext<CR>
:map <C-h> :tabprevious<CR>
:map <F2> :NERDTreeToggle <CR>
:map <F3> :Flisttoggle<CR>

:nunmap <C-a>

set diffexpr=MyDiff()
function MyDiff()
  let opt = '-a --binary '
  if &diffopt =~ 'icase' | let opt = opt . '-i ' | endif
  if &diffopt =~ 'iwhite' | let opt = opt . '-b ' | endif
  let arg1 = v:fname_in
  if arg1 =~ ' ' | let arg1 = '"' . arg1 . '"' | endif
  let arg2 = v:fname_new
  if arg2 =~ ' ' | let arg2 = '"' . arg2 . '"' | endif
  let arg3 = v:fname_out
  if arg3 =~ ' ' | let arg3 = '"' . arg3 . '"' | endif
  if $VIMRUNTIME =~ ' '
    if &sh =~ '\<cmd'
      if empty(&shellxquote)
        let l:shxq_sav = ''
        set shellxquote&
      endif
      let cmd = '"' . $VIMRUNTIME . '\diff"'
    else
      let cmd = substitute($VIMRUNTIME, ' ', '" ', '') . '\diff"'
    endif
  else
    let cmd = $VIMRUNTIME . '\diff'
  endif
  silent execute '!' . cmd . ' ' . opt . arg1 . ' ' . arg2 . ' > ' . arg3
  if exists('l:shxq_sav')
    let &shellxquote=l:shxq_sav
  endif
endfunction

install.sh

git clone https://github.com/Lokaltog/vim-easymotion.git
git clone https://github.com/MarcWeber/vim-addon-mw-utils.git
git clone https://github.com/adoy/vim-php-refactoring-toolbox.git
git clone https://github.com/bling/vim-airline.git
git clone https://github.com/bronson/vim-trailing-whitespace.git
git clone https://github.com/c9s/lftp-sync.vim.git
git clone https://github.com/garbas/vim-snipmate.git
git clone https://github.com/godlygeek/tabular.git
git clone https://github.com/gregsexton/MatchTag.git
git clone https://github.com/honza/vim-snippets.git
git clone https://github.com/jiangmiao/auto-pairs
git clone https://github.com/kien/ctrlp.vim.git
git clone https://github.com/mattn/emmet-vim.git
git clone https://github.com/nanotech/jellybeans.vim.git
git clone https://github.com/pangloss/vim-javascript.git
git clone https://github.com/rhysd/conflict-marker.vim.git
git clone https://github.com/scrooloose/nerdtree.git
git clone https://github.com/scrooloose/syntastic.git
git clone https://github.com/stephpy/vim-php-cs-fixer.git
git clone https://github.com/tmhedberg/matchit.git
git clone https://github.com/tomtom/tcomment_vim.git
git clone https://github.com/tomtom/tlib_vim.git
git clone https://github.com/tpope/vim-surround.git
git clone https://github.com/vim-scripts/AutoComplPop.git
git clone https://github.com/vim-scripts/IndexedSearch.git
git clone https://github.com/vim-scripts/SearchComplete.git
git clone https://github.com/vim-scripts/functionlist.vim.git
git clone https://github.com/vim-scripts/restore_view.vim.git
git clone https://github.com/vim-scripts/smarty-syntax.git
git clone https://github.com/c9s/phpunit.vim.git
git clone https://github.com/captbaritone/better-indent-support-for-php-with-html.git

update.sh

for item in *
do
    if [ -d "$item" ]; then
        echo processing $item
        cd $item
        git pull
        echo finish $item
        printf "\n------------------------------------\n\n"
        cd ..
    fi
done

2015/07/03

PHP-CS-Fixer On Vim

PHP 之前為人所詬病的地方就是沒有統一的撰寫風格以及結構,MVC 觀念興起後,PHP 也出了不少框架,在架構方面得到了很大的改善,但 coding style 還是存在很大的問題,假設 A 公司跟 B 公司都有自己的 convention,那還是沒有所謂的 standard 存在,所以有一個團體制定了一個標準 PHP-FIG,裡面有各種程式碼的撰寫規範,當然這是一種形式上的規範,你不照他那樣寫 PHP 也是會動,只是如果有在使用 github 套件,以及使用 MVC framework 的人,會發現知名熱門的框架幾乎都往這邊靠了,所以如果花點時間去看他的規範參考,之後你接觸其他人的東西速度會快很多。

今天要介紹的不是規範的內容,有慶去的可以去看 Apple 大的投影片,他已經把比較多重要的內容放上來了,今天我要介紹的是工具,PHP-CS-Fixer,這個工具是可以幫你整理現行的 php code,假設你公司已經有許多歷史包袱,但你很想把你看到的內容都整理成 psr-0,psr-2,只要執行這個工具就可以幫你完成,我們來寫一下超不符合規定的 code。

psr.php
$name = 'Chan'; 

if($name !== '')
    echo "hi, my name is {$name}" . PHP_EOL;

for($i = 1; $i <=10; $i++){
    echo $i . PHP_EOL;
}

function test() {

}

上面的程式碼有幾個不符合規定的項目:

  • if 的寫法不可以省略 {}
  • 歪七扭八的 format 如 for( 應該要 for (
  • 結尾有多餘的 trailing white space
  • function 的 {} 要換行

安裝好了 PHP-CS-Fixer 之後,打開 terminal 並跑去我們剛檔案的位置,執行下面的指令:

php-cs-fixer.phar fix psr.php
結果
$name = 'Chan';

if ($name !== '') {
    echo "hi, my name is {$name}".PHP_EOL;
}

for ($i = 1; $i <= 10; ++$i) {
    echo $i.PHP_EOL;
}

function test()
{
}

php-cs-fixer 預設值是跑 symphony 的結構,會改變一些東西,如 空格.空格 會變成 ., for ($i = 1; $i <= 10; $i++) 會變成 for ($i = 1; $i <= 10; ++$i),但完全不會影響現行程式的運行,或許你會不喜歡,那可以加上參數 --level=psr2,這樣的結果就會做出只針對 psr2 的修正。

php-cs-fixer.phar fix psr.php --level=psr2
加上 --level=psr2 結果
$name = 'Chan';

if ($name !== '') {
    echo "hi, my name is {$name}" . PHP_EOL;
}

for ($i = 1; $i <=10; $i++) {
    echo $i . PHP_EOL;
}

function test()
{
}

不過你可以看到 psr-2 並沒有幫你把 $i <=10 變成 $i <= 10 的格式,所以可以憑自己喜好選擇,而 vim 有 vim-php-cs-fixer 可以直接支援在 vim 裡面直接使用 php-cs-fixer,安裝以後執行 <leader>pcf 表示修正目前檔案,<leader>pcd則是修正目前檔案所屬資料夾下所有的檔案,相當方便。

2014/02/21

Vim Macro

在使用 vim 的時候常常會不小心讓狀態列出縣 recording 的字樣,按 q 可以消除,今天不小心看到某篇文章才發現這是 vim 的 macro 功能,而且十分強大,vim 真的是一個可以活到老學到老的工具,來示範幾個範例。

.sample {
    border: 1px; color: red; padding: 4px; margin: 10px;
}

以這個 css class 來講,假設我們要讓每個 ; 後斷行,有非常非常多的方式,marco 的步驟如下

  1. 先將游標移到 border 字樣
  2. 在 visual mode 按下 qa(qa 是指將過程錄到 a 這個暫存,a-z, 0-9 都可以使用)
  3. 按下 f;,此時游標會跑到 ; 上面
  4. 按下 a,游標會跑到 ; 後面並且變成 insert mode
  5. 按下 enter,完成了第一個斷行
  6. 按下 esc 變成 visual mode,在按一次 q 完成錄製
.sample {
    border: 1px;
    color: red; padding: 4px; margin: 10px;
}

現在內容應該會變成這個樣子

將滑鼠移到 color 那行按下 @a(@ 就是執行 macro,後面接要使用的紀錄),斷行自動產生了,如果要到每一行按 @a 也太弱了,可以在前面接數字指定 marco 次數,以這個 case 來說 3@a 就可以完成所有的斷行。

另外示範一個 increment 的範例,在 vim 中使用 ctrl + a 可以針對某個數字增量,ctrl + x 可以減量,但在 windows 裡面 ctrl + a 會被定義為全選,關掉的方式很簡單,打開 .vimrc 檔,在 behave mswin 下加上 :nunmap <C-a>,這樣便會取消全選功能。

a = 1

以這個例子當範例,可以選擇取代法,也可以用 macro

  1. 在 visual model 將游標移到 a = 1 那行
  2. 按下 qa
  3. 使用 yy 複製,按下 p 貼上
  4. 移到新的行數後按 ctrl + a,會發現數字變成 2 了
  5. 按下 q 完成錄製

按下 @a 可以發現新的行數會變成 a = 3,搭配數字便可以做出你需要的數量了。

2013/09/10

Vim With Plugins And Config

Vim

Plugins

目前使用 vim-pathogen 來配置我的 vim plugin,他的好處是只要將檔案放置於 bundle 這個資料夾,插件就會自動去處理所有 plugin 該作的事情。

之前是從 GitHub 下載檔案以後放到 bundle 資料夾,然後不定期去查詢作者有沒有更新的版本,有的話再 download 下來覆蓋,可是每個作者標註版本的習慣不一,甚至有的人根本沒有寫明版本,所以對於更新這件事情十分困擾,於是我採用了新的作法,我將每個 plugin 使用 git clone 的方式 clone 到資料夾,在寫一支 script 去 loop 所有的資料執行 git pull,這樣等於最簡單的 update 方式了。

install.sh

git clone https://github.com/Lokaltog/vim-easymotion.git
git clone https://github.com/MarcWeber/vim-addon-mw-utils.git
git clone https://github.com/Raimondi/delimitMate.git
git clone https://github.com/bling/vim-airline.git
git clone https://github.com/bronson/vim-trailing-whitespace.git
git clone https://github.com/edsono/vim-matchit.git
git clone https://github.com/garbas/vim-snipmate.git
git clone https://github.com/godlygeek/tabular.git
git clone https://github.com/gregsexton/MatchTag.git
git clone https://github.com/honza/vim-snippets.git
git clone https://github.com/kien/ctrlp.vim.git
git clone https://github.com/mattn/emmet-vim.git
git clone https://github.com/nanotech/jellybeans.vim.git
git clone https://github.com/pangloss/vim-javascript.git
git clone https://github.com/scrooloose/nerdtree.git
git clone https://github.com/scrooloose/syntastic.git
git clone https://github.com/tomtom/tcomment_vim.git
git clone https://github.com/tomtom/tlib_vim.git
git clone https://github.com/tpope/vim-surround.git
git clone https://github.com/vim-scripts/AutoComplPop.git
git clone https://github.com/vim-scripts/IndexedSearch.git
git clone https://github.com/vim-scripts/SearchComplete.git
git clone https://github.com/vim-scripts/smarty-syntax.git

update.sh

for item in *
do
    if [ -d "$item" ]; then
     echo processing $item
  cd $item
  git pull
  echo $item finished
  printf "\n------------------------------------\n\n"
  cd ..
 fi
done

只要執行 sudo sh update.sh 程式便會去一一進入每個目錄執行 git pull 了,在實作時遇到一個小插曲,這隻 bash 一開始是在 Windows 的環境下寫的,複製到 Linux 會出現 error,問題出在檔案格式,Windows 斷行使用 CRLF,而 Linux 是 LF,解決方法很簡單,將檔案使用 Vim 打開,執行 :set fileformat=unix,問題就解決了。

Vimrc On Windows

execute pathogen#infect()
syntax on
filetype plugin indent on
:filetype plugin on
au BufRead,BufNewFile *.tpl set filetype=smarty.html
source $VIMRUNTIME/delmenu.vim
language messages zh_TW.utf-8
autocmd FileType php set omnifunc=phpcomplete#CompletePHP
colorscheme jellybeans
:autocmd ColorScheme * hi CursorLineNr guifg=yellow

set cursorline
set number
set nobackup
set fileencoding=utf-8
set tabstop=4
set shiftwidth=4
set expandtab
set guifont=Consolas:h12
set foldcolumn=1
set fileencodings=utf-8,big5,euc-jp,gbk,euc-kr,utf-bom,iso8859-1
set encoding=utf-8
set tenc=utf-8
set winheight=5
set winminheight=5
set winheight=999
set shellslash
set laststatus=2

let g:EasyMotion_leader_key = '<Leader>'
let g:ctrlp_working_path_mode = 0
let g:syntastic_auto_jump = 1
let g:syntastic_php_checkers = ['php']
let g:airline_powerline_fonts = 1

:map <C-t> :tabnew<CR>
:map <C-l> :tabnext<CR>
:map <C-h> :tabprevious<CR>

set nocompatible
source $VIMRUNTIME/vimrc_example.vim
source $VIMRUNTIME/mswin.vim
behave mswin
:nunmap <C-a>

Vimrc On Linux

execute pathogen#infect()
syntax on
filetype plugin indent on
:filetype plugin on
au BufRead,BufNewFile *.tpl set filetype=smarty.html
language messages zh_TW.utf-8
autocmd FileType php set omnifunc=phpcomplete#CompletePHP
colorscheme jellybeans
:autocmd ColorScheme * hi CursorLineNr ctermfg=yellow

set t_Co=256
set cursorline
set number
set nobackup
set fileencoding=utf-8
set tabstop=4
set shiftwidth=4
set expandtab
set foldcolumn=1
set fileencodings=utf-8,big5,euc-jp,gbk,euc-kr,utf-bom,iso8859-1
set encoding=utf-8
set tenc=utf-8
set winheight=5
set winminheight=5
set winheight=999
set autoindent
set backspace=indent,eol,start
set laststatus=2

let g:EasyMotion_leader_key = '<Leader>'
let g:ctrlp_working_path_mode = 0
let g:syntastic_auto_jump = 1
let g:syntastic_php_checkers = ['php']
let g:airline_powerline_fonts = 1

:map <C-t> :tabnew<CR>
:map <C-l> :tabnext<CR>
:map <C-h> :tabprevious<CR>

2013/03/31

VIM 搜尋與取代同時加入遞增號碼

我們常常使用 y 來複製重複的程式,尤其是陣列,例如:

$arr[] = '';

使用 yy 後執行 5p,便會產生六個陣列

<?php
$arr[] = '';
$arr[] = '';
$arr[] = '';
$arr[] = '';
$arr[] = '';
$arr[] = '';
?>

今天學到一個技巧可以帶入遞增的數字

:let i=1 | 2,7g/\[/s//\='['.i/ | let i=i+1

便可以得到下面的結果

<?php
$arr[1] = '';
$arr[2] = '';
$arr[3] = '';
$arr[4] = '';
$arr[5] = '';
$arr[6] = '';
?>

2012/11/08

Notepad++、Vim 加入 Consolas 字型,Windows、Linux 適用

身為一個 web developer,最常做的事情就是打字,每天面對密密麻麻的英文,選擇一個舒適的字體對視覺及心情來說都有很大的影響,很多人會推 Monaco font,個人是喜歡 Consolas 的樣式,簡單寫一下如何在 Linux 安裝 Consolas 字型,讓 notepad++ 以及 vim 可以吃到。

notepad++

vim

我的測試環境是 Mint,我想 Ubuntu 系列應該不會差太多,Mint 可以直接吃 Windows 的 font,所以只要把 C:\Windows\Fonts\ 裡面有關 Consolas 的 ttf 檔案複製出來,直接丟到 Linux 的 fonts 資料夾就可以用,Mint 的路徑為 /usr/share/fonts/truetype,我不確定是不是一定要放到 truetype 這個目錄裡面,不過網路上有人建議這樣放,但我想放在 fonts 下面應該也可 run,如果不確定 fonts 資料夾在哪可以使用 whereis fonts 來找找看,複製完之後執行刷新字型的 command

sudo fc-cache

fc-list | grep Consolas
# 接著查看有沒有安裝成功

Consolas:style=Italic
Consolas:style=Bold
Consolas:style=Bold Italic
Consolas:style=Regular
# 看到這些內容就表示有抓到新字型了
在 terminal 的情況下,無法讓 vim 單獨讀取字型,必須修改 terminal 的設定

改完以後整個 terminal 介面就變美美的啦

notepad++ 就簡單許多,選自訂 -> 設定程式語言格式,在字型部分選擇 Consolas 即可

Windows gvim 的部分,只要在 vimrc 加上 set guifont=Consolas:h11 即可,h 後面是指字級,可以隨喜好調整

2012/10/24

VIM 讀取文件範圍

vim 的 :r 功能可以讀入指定檔案內容到目前的檔案,例如

:r test.html
# vim 會在游標處將 test.html 的所有文字讀入

:10r test.html
# 在第十行插入 test.html 的內容

不過如果我們只是要插入該檔案某個範圍,vim 本身並沒有提供相關的支援,必須透過語法的結合達到此目的,Windows, Linux 都適用

:r! sed -n 6,12p test.html
# 讀入 test.html 六到十行的內容

:10r! sed -n 6p test.html
# 於第十行讀入 test.html 第六行的內容

2011/10/15

VIM Note

手動 Fold

  • zf 將選取的範圍 fold 起來
  • zd 刪除游標上的 fold
  • zo 打開游標上的 fold
  • zO 遞迴地打開游標上底下所有的 fold
  • zc 把游標上的 fold 折起來
  • zC 遞迴地折起游標上底下所有的 fold
  • zM 把整個檔案所有的 fold 都折起來
  • zR 把整個檔案所有的 fold 都打開
  • :2,6fold 將 2-6 行 fold
  • :mkview 記憶手動 fold
  • :loadview load 手動 fold

檔案比較

  • vimdiff FILELEFT FILERIGHT 如果還沒開啟某個檔案,可以在指令列這樣下
  • diffsplit FILE_RIGHT 水平分割開啟比較檔案
  • vertical diffsplit FILE_RIGHT 垂直分割開啟比較檔案
  • :diffthis 將看到的視窗使用檔案比較功能
  • :diffoff 關閉檔案比較
  • :set scrollbind 同步捲動
  • :set noscrollbind 停止同步捲動
  • ]c 移到下一個差異點
  • [c 移到上一個差異點
  • dp 將目前的內容放置到另一個視窗
  • do 將另一個視窗的內容放置到目前的視窗
  • :diffupdate 手動刷新比較結果

自動 Fold

  • set foldmethod =
    • manual 手動摺疊
    • indent 級別折疊
    • syntax 語法折疊
    • marker 所有文本將按照特定標記(默認為{{{和}}})自動摺疊
  • set foldlevel=0 控制可以看見的折疊層級

搜尋與取代

  • / 在 c-mode 的情形下,按 / 就會在左下角出現一個 /,然後鍵入您要尋找的字串,按個 Enter 就會開始找
  • ? 和 / 相同,只是 / 是向前(下)找,? 則是向後(上)找
  • n 繼續尋找
  • N 繼續尋找(反向)
  • /\c 不分大小寫搜尋,譬如要搜尋 test,/\ctest 可以搜尋到 test, Test, tEst 等等
  • :set nohlsearch 關閉搜尋的 highlight 效果
  • :%s/a/b/gi 不分大小寫將 a 取代為 b
  • :2,6s/a/b/gi 不分大小寫將 2,6 行 a 取代為 b

強大的檔案搜尋 vimgrep

notepad++ 跟 Dreamweaver 都可以針對某個資料夾的檔案做原始碼關鍵字的搜尋,沒想到 vim 也可以,真的太強大了,假設今天要搜尋 test 資料夾裡面所有含 $name 的檔案,code 只要這樣下。

:vimgrep /$name/ c:\AppServ\www\test\*

不分大小寫的話直接加上 \c 就可以了。

:vimgrep /\c$name/ c:\AppServ\www\test\*

複合式的搜尋,下方指令會搜尋當下資料夾的檔案跟 template 下的所有檔案

:vimgrep /$name/ * template/*

搜尋包含全部子目錄

:vimgrep /$name/ **/*

vimgrep 其他功能介紹

  • :cw - 開啟符合檔案列表
  • :cn - 下一個檔案
  • :cN - :cn 的相反
  • :cp - 上一個檔案
  • :cP - :cp 的相反
  • :cc - 顯示目前編輯的檔案

小技巧

修改符號內容

假設有個內容是這樣 "aaa-bbb-ccc",如果我們移到 aaa 按下 cw 想要修改內容,會變成 "-bbb- ccc,但其實我們的目的是要修改掉整個 "" 的內容怎麼辦呢,只要在該 "" 範圍內、按下 ci",便會把 "" 內的內容作變更的動作,同理,要清除可以用 di",複製則是 yi",若使用 ca" 則是把 " 一併修改,ciw 會修改一個整個字,跟 ci 的差別在於 ci 只會修改目前 cursor 之後的字,而 ciw 會判斷前面,ci( 以及 ci{ 會修改 ( 以及 { 裡面的內文,ca( ca{ 會連 ( 以及 { 一起取代掉。

修改標籤內容

另外一種常遇到的情況就是 <a href='"#"'>aaa-bbb-ccc</a>,我們想要修改 <a> 標籤內的內容,此時只要使用 cit,t = tag 的意思,cat 則是連 tag 本身都修改。

段落前後加上文字

如果今天有一個段落的內容如下:

aaaaa
bbbbbbb
ccccc

今天想要在前方或後方加入 x 這個字的話,前方可能還好,可以用區塊編輯的方法,但後方並沒有對齊,不能這樣做,此時我們可以用取代的方式。

  • :1,3s/^/x/gi - 前方加 x
  • :1,3s/$/x/gi - 後方加 x

複製、修改、刪除區段

  • dfx - 刪除到 x
  • dtx - 刪除到 x 為止
  • d/word - 刪除到 word 為止

此技巧可以搭配數字使用,例如說 d4f",便會刪除至 4 個 "。

Hot Key

  • $ 行尾
  • :2,6m12 將第 2 行至第 6 行移動到 12 行之後
  • :2,6t12 將第 2 行至第 6 行複製到 12 行之後
  • :command! 這個 ! 強迫中止目前正在編輯的動作,而去執行所下的指令
  • :find **/aa.php 在所有目錄下搜尋 aa.php
  • :lcd 改變當下目錄
  • :m+ 將游標所在位置往下移動一行
  • :m-2 將游標所在位置往上移動一行
  • :m20 將游標所在位置移到第 20 行
  • :pwd 顯示當下目錄
  • :q 及 :q! 是對目前編輯中的檔案作用
  • :q 如本文有修改而沒存檔,會警告,且無法離開(quit)
  • :q! 捨棄所有修改,強迫離開
  • :qa 或 :qa! 來整個離開 vim,a 就是 all 的意思
  • :sort i 忽略大小寫
  • :sort n 依照字數排序
  • :sort u 移除重複的內容
  • :sort 昇冪排序
  • :sort! 降冪排序
  • :sp 水平分割視窗
  • :tabc 關閉標籤頁
  • :tabe filename 在新標籤頁打開一個檔案
  • :tabl 最後一個標籤頁
  • :tabm [N] 移動到第 N 順位
  • :tabn 下一個標籤頁 或是 gt,C-PageDown
  • :tabo 關閉其他標籤頁
  • :tabp 上一個標籤頁 或是 gT,C-PageUp
  • :tabr 第一個標籤頁
  • :tabs 顯示所有標籤頁
  • :vs 垂直分割視窗
  • :w 檔名 另存他檔不加檔名就是寫入原檔(write)
  • :wq 存檔後離開縱使檔案未曾修改也是會再存一次檔
  • :x 也是存檔後離開,但如果檔案沒有修改,則不會做存檔的動作
  • >> 整行向右移一個 shiftwidth(預設是 8 個字元,可重設)
  • >> 整行向左移一個 shiftwidth(預設是 8 個字元,可重設)
  • ^ 行首第一個字元
  • a 在游標所在字元後開始輸入文字(append)
  • A 在行尾開始輸入文字
  • B 同上,但會忽略一些標點符號
  • b 移至前一個字字首
  • c confirm,每次替換前會詢問
  • C 取代至行尾,即游標所在處以後的字都會被替換或 c$
  • c0 取代至行首,或 c^
  • cc 取代整行內容或大寫 S 亦可
  • Crtl+r 這個也是很重要,就是 redo 鍵
  • Ctrl+w+< 增加寬度
  • Ctrl+w+= 平均視窗尺寸
  • Ctrl+w+> 減少寬度
  • Ctrl-b 整個視窗往上移動
  • Ctrl-d 在編輯模式下,會將開行往左移動
  • Ctrl-e 視窗逐行下移
  • Ctrl-f 整個視窗往下移動
  • Ctrl-t 在編輯模式下,會將開行往右移動
  • Ctrl-v 這是方塊標示(block visual),可縱向標示矩形區域再按一次 Ctrl-v 就會結束 v-mode結束 v-mode 的方式亦可使用 Esc 鍵,或統一使用 Ctrl-c
  • Ctrl-w f 開一新視窗,並編輯游標所在處之 word 為檔名的檔案
  • Ctrl-w j 移至下視窗
  • Ctrl-w k 移至上視窗
  • Ctrl-w n 即 :new開一空的新視窗
  • Ctrl-w o 即 :only! 使游標所在之視窗,成為目前唯一顯示的視窗其它視窗會隱藏起來
  • Ctrl-w q 即 :q 結束分割出來的視窗
  • Ctrl-w r 向右或向下輪替視窗
  • Ctrl-w R 與上方相反方向
  • Ctrl-w s 即 :sp(lit),會開一新視窗,且原檔分屬兩個視窗
  • Ctrl-w x 交換同列或同欄視窗位置
  • Ctrl-w X 與上方相反
  • Ctrl-w++ 增加高度
  • Ctrl-w+- 減少高度
  • cw 替換一個英文字(word),中文不適用(change)
  • D 刪至行尾,或 d$(含游標所在處字元)
  • d 刪除標示區內容
  • d0 刪至行首,或 d^(不含游標所在處字元)
  • d1G 刪至檔首或 dgg(只能用於 vim)
  • dd 刪除一整行(delete line)
  • dG 刪至檔尾
  • dw 刪除一個字(delete word)不能適用於中文
  • e 不顯示 error
  • E 同上,但會忽略一些標點符號
  • e 移至後一個字字尾
  • g globe,不詢問,整行替換
  • G 移至檔尾(最後一行的第一個非空白字元處)
  • gg 移至檔首(第一行之第一個非空白字元處)
  • gUU 整行轉大寫
  • guu 整行轉小寫
  • g~~ 整行大小寫反轉
  • h j k l 左 下 上 右
  • H 移至螢幕頂第一個非空白字元
  • i ignore 不分大小寫
  • i 在游標所在字元前開始輸入文字(insert)
  • I 在行首開始輸入文字
  • J 將下一行整行接至本行(Joint)
  • L 移至螢幕底第一個非空白字元,內文內容並未動,只是游標在動而已
  • M 移至螢幕中間第一個非空白字元
  • O 在游標所在行上開一新行來輸入文字
  • o 在游標所在行下開一新行來輸入文字(open)
  • P 大寫 P 代表貼至游標前(上)
  • p 小寫 p 代表貼至游標後(下)
  • pattern 就是要被替換掉的字串,可以用 regexp 來表示
  • R 取代字元至按 Esc 為止
  • r 取代游標所在處之字元vi(m)
  • range 指的是範圍,1,7 指從第一行至第七行,1,$ 指從第一行至最後一行,也就是整篇文章,也可以 % 代表
  • resize n 設定視窗高度
  • s 替換一個字元為您所輸入的字串和 R 不同,R 是覆蓋式的取代,s 則是插入式的取代,您可親自實驗看看ㄟ!是小寫的 s
  • Shift-> 標示區內容向右移一個 Tab
  • Shift-< 標示區內容向左移一個 Tab
  • Shift-h 移到該視窗頂端
  • Shift-l 移到該視窗尾端
  • Shift-m 移到該視窗中央
  • string 將 pattern 由 string 所取代
  • U 在游標沒離開本行之前,回復所有編輯動作
  • u 這個太重要了,就是 undo,傳統的 vi 僅支援一次 undo,vim 及 elvis 就不只了,vim 是沒有限制的
  • V 大寫 V,這是行標示(line visual),按下 V 後會整行標示起來(包括行首前空白的部分),您移動上下鍵,會標示多行mouse 連按三次左鈕,也是屬於此類的標示再按一次 V 就會結束 v-mode
  • v 小寫 v,這是屬於字元標示(character visual),按下 v 後您就可以移動游標,游標走過的地方就會標示起來再按一次 v 就會結束 v-mode您用 mouse 拉出的標示區也是屬於這類的標示
  • vertical resize n 設定視窗寬度
  • W 同上,但會忽略一些標點符號
  • w 移至次一個字(word)字首
  • windows 系統下 Ctrl-v 是複製鍵,可以使用 Ctrl-Q 來替代
  • X 刪除游標前之字元不可使用 Backspace 鍵
  • x 刪除游標所在處之字元在 vim 及 elvis 亦可用 Del 鍵
  • y 複製標示區內容
  • y$ 複製至行尾含游標所在處字元
  • y1G 複製至檔首
  • y2w 複製兩個字
  • y^ 複製至行首,或 y0不含游標所在處字元
  • yG 複製至檔尾
  • yw 複製一個 word
  • yy 複製游標所在行整行或大寫一個 Y,2yy 或 y2y 複製兩行
  • zb 將游標位置拉至螢幕底部
  • zt 將游標位置拉至螢幕頂部
  • ZZ 和 :x 完全一樣,隨您高興用哪一個
  • zz 將游標位置拉至螢幕中間
  • ~ 游標所在處之大小寫互換當然不能用於中文