沒穿方服

索引

顯示╱隱藏內文

git config 調整

Git 2.0 RC 1 了,確認一下 push.default 設定。

[push]
  ; git 2.0 以前預設為 matching, 會將所有同名 branch push 出去
  ; git 1.7.6 以前可以用 tracking (deprecated),等於後來的 upstream
  ; git 1.7.11 開始可以使用 simple,即 2.0 預設值
  default = tracking
  default = simple

參考 git-config Documentationpush.default 條。 進行 git push,沒指定 refspec 時,舊預設值 matching 會把 local 的所有 branch,只要 remote 有一樣名字的就推出去。 但通常我們只會改一個 branch,也只有這個 branch 是要給別人看的,如果意外把其它 local branch 也推出去就糟了。 所以選 simple 比較適合,會先試 upstream 的作法把「目前的」branch 推到它的 upstream(可以用 git branchgit push--set-upstream 設定,或直接在 .git/config 中設 [branch.foo] 的 remote);如果 git 找不到已知的 upstream,會再嘗試 current 作法,推到與目前 branch 同名的 branch。


看過 doc 後也順便改了:

  • Config 的各個 key 不分大小寫,但預設產生的是全小寫,於是手動改成 camelCase。
  • [log]
      abbrevCommit = true

    只顯示 hash 的前幾個字,這樣 tmux copy-mode 複製時,用 word selection 取到的東西比較簡短。

  • git branch 的 alias 預設加上 --verbose 選項。

    zshrc:

    alias gitb='git branch -v'

    git branch -v

移除 Web Developer 後發現少了「清除 domain cookie」功能,於是補寫一個 FireGestures script,設定為 ← ↓ → ↑ ↓ (LDRUD)Cookie、上下為關閉)取代之。

先詢問再砍 結束時 alert 找不到 domain cookie 時

// Require Firefox 17
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/Services.jsm");

var
  manager = Services.cookies,
  prompter = Services.prompt,
  hostname = gBrowser.currentURI.host,
  cookies = manager.getCookiesFromHost(hostname),
  cookie,
  dialogTitle = 'FireGestures script',
  kills = [];

while (cookies.hasMoreElements()) {
  cookie = cookies.getNext().QueryInterface(Ci.nsICookie2);
  if (cookie.rawHost === hostname || hostname.endsWith('.' + cookie.rawHost)) {
    kills.push(cookie);
  }
}


if (kills.length) {
  if (prompter.confirm(
        null,
        dialogTitle,
        [
          hostname,
          '移除 ' + kills.length + " 個曲奇?",
          "\n  " + kills.map(function (cookie) { return cookie.name; }).join("\n  ")
        ].join("\n")
      )) {
    kills.forEach(function (cookie) {
      manager.remove(
        cookie.host,
        cookie.name,
        cookie.path,
        false
      );
    });
    window.alert('已移除 ' + kills.length + " 個曲奇。");
  }
} else {
  prompter.alert(
    null,
    dialogTitle,
    hostname + "\n沒有需移除的曲奇。"
  );
}

Gblame 運用

Gblame 是什麼

tpope/vim-fugitive 提供的指令,把 git blame 結果顯示在分割視窗。
裡面按 -~P 可以對其它版本再 blame(詳見 doc),比直接在 command line 操作方便多了。

Gblame 畫面


開啟後自動 resize 到作者名

:Gblame 打開後,預設會顯示到 Date,很佔畫面,按 A 可以縮到 Author。

煩的是沒有選項能自動這件事,只好另設一個 command,在 :Gblame 後多送一個 A

command! -nargs=0 GBlameA Gblame | call <SID>fugitiveblame_after()
function! s:fugitiveblame_after() "{{{
  call feedkeys('A')
endfunction "}}}

然後用 tyru/vim-altercmd 方便輸入……

AlterCommand gb[lame] GBlameA

bling/vim-airline 狀態列

很微小的修改,原本狀態列會顯示 fugitive tmp file 的名稱,我把它改成 "Gblame"。

function! AirlineGblame(...)
  if &filetype == 'fugitiveblame'
    let w:airline_section_a = ''
    let w:airline_section_b = ''
    let w:airline_section_c = 'Gblame'
    let w:airline_section_y = ''
  endif
endfunction
let g:airline_statusline_funcrefs = []
call airline#add_statusline_func('AirlineGblame')

Git compare

配合 bootleq/vim-gitdiffall 使用, 按 gf 將檔案變更以 vim diff 開在新 tab,看那個 revision 改了什麼:

gitdiffall 開在新 tab

<LocalLeader>gf 則是開啟新的 tmux window,把該版本變更的檔案全部打開:

gitdiffall 開在新的 tmux window

function! s:fugitiveblame_gitdiffall(all) "{{{
  let rev = matchstr(getline('.'), '\v^\w{7}')
  let buffer = fugitive#buffer(bufname(b:fugitive_blamed_bufnr))
  if a:all
    call TmuxNewWindow({
          \   "text": "gitdiffall @" . rev,
          \   "title": '⎇',
          \   "directory": buffer.repo().tree()
          \ })
  else
    execute printf("tabnew %s | silent GitDiff @%s", buffer.path(), rev)
  endif
endfunction "}}}

autocmd! my_vimrc FileType fugitiveblame
      \ nnoremap <buffer> gf :call <SID>fugitiveblame_gitdiffall(0)<CR> |
      \ nnoremap <buffer> <LocalLeader>gf :call <SID>fugitiveblame_gitdiffall(1)<CR>
function! TmuxNewWindow(...) "{{{
  let options = a:0 ? a:1 : {}
  let text = get(options, 'text', '')
  let title = get(options, 'title', '')
  let directory = get(options, 'directory', getcwd())
  let cmd = 'tmux new-window -a '
        \ . (empty(title) ? '' : printf('-n %s', shellescape(title)))
        \ . printf(' -c %s', shellescape(directory))
  call system(cmd)
  if !empty(text)
    let cmd = printf('tmux set-buffer %s \; paste-buffer -d \; send-keys Enter', shellescape(text))
    call system(cmd)
  endif
endfunction "}}}

這裡比較悶的是 Gblame 的 mapping 都寫死死,最後只好選 gf 來用。
看 issue 感覺是 tpope 不大想理 mapping 的彈性。

一、tpope/vim-rails

我最常用的是 :RT:Tmodel foo:A


二、basyura/unite-rails

可設定按下 ,fR 就打開 Unite 介面,選擇 Rails 相關的 source。

nnoremap [unite] <Nop>
nmap <LocalLeader>f [unite]
nnoremap <silent> [unite]R :<C-U>Unite -start-insert -input=rails/ source<CR>

於是按下 ,fR 就顯示
Unite rails/xxx

接著選擇 initializer,就能進入 rails/initializer 這個 source 的畫面了。
※下圖我按了 ke 示範一下 filter 功能
搜尋 initializers


這兩個 plugin 的功能都不限於「尋找檔案」,這篇就不多說了。

沒有 LiveReload 也過得很好

「雙螢幕 + FireGestures 搖擺手勢(按住滑鼠右鍵再按左鍵)重新載入網頁」 —— 至少比按 F5 快多了。

目前環境

Windows 7 的 Firefox 21 beta + LiveReload Firefox extension,
Ubuntu VM 的 Rails + guard-livereload

我的 LiveReload 大概已經一兩年沒辦法用了,I Don't Know Why,最近被問到才重啟調查,發現在瀏覽器直接測試 WebSocket(可以用 WebSocket.org | Echo Test 測)是可以和 VM 裡的 LiveReload server 來往的,那八成是瀏覽器的擴充套件出狀況。

惱人的 LiveReload Firefox 擴充套件

LiveReload 官網提供的 2.0.8 版 xpi 因為還沒包含 Pull Request #8,所以應該是不堪用的,此外還有按鈕無法移除、連線錯誤沒有警告(有時甚至毫無反應)等煩人問題。

另一關鍵是沒有選項可以調整連線的 hostport,預設是 127.0.0.1 和 35729,我 VM 裡的 server 就不是用這兩個,當然連不上。

註:LiveReload 現在的設計是 server 在頁面插入 livereload.js,讓 client 從中取得 host 和 port。 所以也許是我的 guard-livereload 版本太舊(0.3.1),或者頁面需要另做修改。

最後對策是改 xpi 內容,讓它讀取 Firefox 自訂選項 extensions.livereload.fc.hostportfc 只是隨便定的名字),具體是在 global.js 的 beforeEnablingFirst 加入:

// Use custom preferences
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  .getService(Components.interfaces.nsIPrefService);
prefs = prefs.getBranch("extensions.livereload.fc.");
if (prefs.getCharPref('host')) {
  this.host = prefs.getCharPref('host');
}
if (prefs.getCharPref('port')) {
  this.port = prefs.getCharPref('port');
}