My git alias in .bashrc
CREATED:
UPDATED:
My favorite alias are g
, gau
, gc
, gt
, gl
,and gdc
.
# {{ git
# Git alias
function gitshortlogcmd () {
git log --date=short --decorate --graph "$@"
}
function gitlogcmd () {
git log --date=short --decorate --graph --pretty=format:'%C(yellow)%h%Creset%C(green)%d%Creset %ad %s %Cred(%an)%Creset' "$@"
}
alias g="git status --short -b"
alias gb="git branch"
alias gn="git status --untracked-files=no --short -b"
alias gfl="git diff-tree --no-commit-id --name-only -r"
alias ga="git add"
alias gr="git rebase -i `git remote`/`git symbolic-ref --short HEAD`"
alias gap='git add --patch'
alias gai='git add -i'
alias gau="git add -u"
alias gc="git commit -m"
alias gca="git commit --amend"
alias gja="git --no-pager commit --amend --reuse-message=HEAD" # git just amend
alias gt="git stash"
alias gta="git stash apply"
alias gmt="git mergetool"
alias gl="gitlogcmd"
alias glp="gitlogcmd -p"
alias gls="gitlogcmd --stat"
alias gnb="git checkout -b"
alias gss="git show --stat"
alias gsl="git log --pretty=format:'%h %s (%an)' --date=short -n1 | pclip"
alias gd="git diff"
alias gds="git diff --stat"
alias gdc="git diff --cached"
alias gdcs="git diff --cached --stat"
alias gps="git push"
alias gpf="git push --force"
alias gpl="git pull"
alias gpr="git pull -r"
alias cg='cd $(git rev-parse --show-toplevel)' #goto root dir
alias ghe='git diff --name-only --diff-filter=U|grep "\.html\|\.min\.js"|xargs -I{} sh -c "git checkout --theirs {} && git add {}"'
alias gme='git diff --name-only --diff-filter=U|grep "\.html\|\.min\.js"|xargs -I{} sh -c "git checkout --our {} && git add {}"'
# delete selected local branch
alias gdd='git branch -D $(git branch | sed "s/[\* ]\+//g" | ~/bin/percol.py)'
# show diff from the branch to current HEAD
alias gdp='git diff $(git branch | sed "s/[\* ]\+//g" | ~/bin/percol.py)..HEAD'
alias grh='git reset --hard HEAD'
alias gr1='git reset --hard HEAD^'
alias gr2='git reset --hard HEAD^^'
alias gs="git show"
function gsh {
git log --date=short --pretty=format:'%h%d %ad %s (%an)' | python ~/bin/percol.py | awk '{print $1}' | xargs -i git show {}
}
function gcn()
{
# commit with timestamp
local d=`date +%m%d-%H%M%S`
git add -u . && git commit -m ${d}
}
# find full path of file who under git controll
# the optional parameter is the keyword
function gf()
{
if [ -z "$1" ]; then
local cli=`git ls-tree -r HEAD --name-status | python ~/bin/percol.py`
else
local cli=`git ls-tree -r HEAD --name-status | grep "$1" | python ~/bin/percol.py`
fi
local rlt=$(cd $(dirname $cli); pwd)/$(basename $cli)
echo ${rlt}
echo -n ${rlt} | pclip
}
function glwho () {
local guy=`git shortlog -sn | ~/bin/percol.py | sed 's/^\s*[0-9]\+\s*//g'`
# space is a problem, so we can't use gitshortlogcmd here
gitshortlogcmd --pretty=format:'%C(yellow)%h%Creset%C(green)%d%Creset %ad %s %Cred(%an)%Creset' --author="$guy" "$@"
}
function gfp () {
if [ -z "$1" ]; then
echo "Usage: gfp since [file]"
echo " Just alias of 'git format-patch -n --stdout since -- [file]'"
echo " 'gfp since | git am' to apply the patch"
fi
git format-patch -n --stdout $1 -- $2
}
function gcnb () {
local remoteb=$(git branch --all | sed '/no branch/d' | ~/bin/percol.py)
local localb=$(echo $remoteb | sed 's/^ *remotes\/[a-z]*\///g')
git checkout -b $localb $remoteb
}
function grb () {
# switch to recent git branch or just another branch
local crtb=`git branch | grep \*`
local ptn="no branch"
# compatible way to detect sub-strin in bash
# @see http://stackoverflow.com/questions/229551/string-contains-in-bash
if [ -z "${crtb##*$ptn*}" ]; then
# detached HEAD
git checkout $(git branch | sed '/no branch/d' | ~/bin/percol.py)
else
local myrbs=`git for-each-ref --sort=-committerdate refs/heads/ | sed -e s%.*refs\/heads\/%%g`
local crb=`git symbolic-ref --short HEAD`
git checkout `echo "$myrbs" | sed '/$crb/d' | ~/bin/percol.py`
fi
}
# rebase on LOCAL branches
function gri () {
local b=`git branch | sed 's/[\* ]\+//g' | ~/bin/percol.py`
git rebase -i ${b}
}
# rebase on ALL braches
function gra () {
local b=`git branch --all | sed 's/[\* ]\+//g' | sed 's/remotes\///g' | ~/bin/percol.py`
git rebase -i ${b}
}
# select a local git branch
function gsb () {
local b=`git branch | sed "s/[\* ]\+//g" | ~/bin/percol.py`
echo -n ${b} | pclip;
echo ${b}
}
# print current branch name
function gcb () {
local crb=`git symbolic-ref --short HEAD`
echo -n ${crb} | pclip;
echo ${crb}
}
# new local branch based on remote branch
function gnr () {
local myrb=`git for-each-ref --sort=-committerdate refs/remotes/ | sed -e s%.*refs\/remotes\/%%g | ~/bin/percol.py`
local mylb=`echo -n $myrb | sed 's/.*\/\([^\/]\+\)$/\1/'`
git checkout -b $mylb $myrb
}
function gchk () {
if [ -z "$1" ]; then
echo "Usage: gchk commit_id"
echo "reset hard certain version of current working directory"
else
rm -rf $PWD/*
git checkout $1 -- $PWD
fi
}
function git2fullpath {
local fullpath=$(git rev-parse --show-toplevel)/$1
echo -n $fullpath | pclip
echo $fullpath
}
function glf () {
local str=`git --no-pager log --oneline --name-only $* | ~/bin/percol.py`
git2fullpath $str
}
function gsf () {
local str=`git --no-pager show --pretty=format:'%h %s (%an)' --name-only $* | ~/bin/percol.py`
git2fullpath $str
}
function gdf () {
local str=`git --no-pager diff --oneline --name-only $*| ~/bin/percol.py`
git2fullpath $str
}
function gdcf () {
local str=`git --no-pager diff --oneline --cached --name-only $* | ~/bin/percol.py`
git2fullpath $str
}
function ggr () {
if [ -z "$1" ]; then
echo "Grep files under git controll"
echo "Usage: ggr [filename-pattern] text-pattern"
elif [ $# -eq "1" ]; then
git ls-tree -r HEAD --name-only | xargs grep -sn "$1"
elif [ $# -eq "2" ]; then
git ls-tree -r HEAD --name-only | grep "$1" | xargs grep -sn --color -E "$2"
fi
}
function grpc() {
if [ -z "$1" ]; then
echo "Replace the content of file in latest git commit"
echo "Usage: grpc [commit-hash] old_string new_string (string could be perl regex)"
elif [ $# -eq "2" ]; then
git diff-tree --no-commit-id --name-only -r HEAD | xargs perl -pi -e "s/$1/$2/g"
elif [ $# -eq "3" ]; then
git diff-tree --no-commit-id --name-only -r $1 | xargs perl -pi -e "s/$2/$3/g"
fi
}
function grpf() {
if [ -z "$1" ]; then
echo "Replace the content of file under git"
echo "Usage: grpf old_string new_string (string could be perl regex)"
elif [ $# -eq "2" ]; then
git grep -l "$1" | xargs perl -pi -e "s/$1/$2/g"
fi
}
function gp() {
if [ $# = 0 ]; then
local from=`gitshortlogcmd --pretty=format:'%h %ad %s (%an)' $* | ~/bin/percol.py|sed -e"s/^[ *|]*\([a-z0-9]*\) .*$/\1/"`;
local fn=from-$from-`date +%Y%m%d-%H%M`.patch
git format-patch -n --stdout $from > $fn && ls $fn
else
local fn=from-$1-`date +%Y%m%d-%H%M`.patch
git format-patch -n --stdout $1 > $fn && ls $fn
fi;
}
# }}
Emacs中的完美多窗口操作
典型的工作流
- 在两个子窗口中对比文件内容
- 打开更多的窗口以参考其他信息.
- 对某个窗口内容比较有兴趣,跳转到该窗口,将该窗口最大化
- 看完最大化的窗口内容后,undo最大化操作,重新回到早先的多个小窗口模式以便继续纵览全局
将子窗口自动编号,然后按M-0…9跳转(最爱)
安装window-numbering.el,然后在.emacs中添加以下代码,
(require 'window-numbering) (window-numbering-mode 1)
undo/redo之前的窗口操作(最爱)
安装Winner Mode,然后在.emacs中添加以下代码,
(winner-mode 1) ;; copied from http://puntoblogspot.blogspot.com/2011/05/undo-layouts-in-emacs.html (global-set-key (kbd "C-x 4 u") 'winner-undo) (global-set-key (kbd "C-x 4 r") 'winner-redo)
焦点移动到下一窗口(常用)
M-x other-window,快捷键是`C-x o`.
水平/垂直切分当前窗口(常用)
快捷键C-x 2/3
将当前子窗口最大化(常用)
M-x delete-other-windows,快捷键`C-x 1`.
删除当前子窗口(偶尔用)
M-x delete-window (快捷键`C-x 0`)
顺便说一下,M-x kill-buffer-and-window (快捷键`C-x 4 0`),我现在用得更多 些.
移动焦点到上下左右的窗口(基本不用)
因我较喜欢vi快捷键,所以我安装了Evil Mode.快捷键和Vi一样. C-w h/j/k/l移动至各方向的子窗口.
存储/载入窗口布局到register(基本不用)
`C-x r w`存储,`C-x r j`载入.
Convert TEX to PDF
Install TexLive in your OS.
Install latex2pdf
which is dependent on TexLive.
cpan App::cpanminus # handy tool to install cpan module
cpanm Template # Template is missing on cygwin
cpanm latex2pdf # finally
Convert now!
pdf2latex cv.tex
Install perl module through source package on cygwin by using cpanm
I failed to install package "Template" by running `cpanm Template'.
It's because the binary package requires gcc4 while on my cygwin only gcc3 available.
So I install it from source package (with some hack, of course),
cpanm --look Template # Download and unpack the distribution and then open the directory with your shellI
cpanm . #install from local directory
Updated: The simpler solution is to install gcc4 at cygwin.
How to convert org to PDF
Install TexLive. The org-mode
has some handy function to locate the TexLive. Press C-c C-e p
to convert.
At Cygwin and Linux, installing TexLive could be installed by their package system.
At macOS, I use the TexLive source package (install-tl-unx.tar.gz). After installation, environment varaibles need be set.
Bash shell requires setup in ~/.bashrc
,
if [[ `uname -s` == *Darwin* ]]; then
#tex live on OS X
export PATH=/usr/local/texlive/2011/bin/universal-darwin:$PATH
export MANPATH=/usr/local/texlive/2011/texmf/doc/man:$MANPAH
export INFOPATH=/usr/local/texlive/2011/texmf/doc/info:$INFOPATH
fi
Notes on Emacs chat between John Wiegley and Sacha Chua
See http://sachachua.com/blog/2012/07/transcript-emacs-chat-john-wiegley/ for the video and transcript.
I only record key points,
- Use gnus heavily
- ERC in another Emacs instance
- Look at Magit buffer to get overview
- Use built in vc mode, `C-x v =' to get diff of current file
- One single org, other seven are archives
- Helm (fork of anything.el)
- Gnus read mail and rss (gwene), Adaptive scoring is good.
- fetchmail to fetch from Gmail
- Organize Structure (rename/moving files folders)
- Twenty items in hot list in org-mode linking to other lists and areas of machine
- Dropbox to record voice at http://dropbox.com and org-mode hook to get voice message
- M-m to call `org-capture'
- 'Quick Keys' on Mac plus some apple script (Viewing page in Chrome, M-n to activate emacs, put a link)
- Emacs can view PDF
- Reading Emacs manual from the scratch
- Emacspeak to read the manual
- Ledger for the accounting
How to configure yasnippet 0.7.0 and use it with Auto-Complete-Mode
I will only talk about how to set up yasnippet 0.7.0 or higher version.
If you follow `normal install` way, setup is simple
See its official documentation.
Install the yasnippet into somewhere and add following code into your .emacs:
(add-to-list 'load-path
"~/.emacs.d/plugins/yasnippet-x.y.z")
(require 'yasnippet) ;; not yasnippet-bundle
(yas/initialize)
(yas/load-directory "~/.emacs.d/plugins/yasnippet-x.y.z/snippets")
If you use elpa package system, setup is even simpler
After installation, you only need two lines in .emacs.
(require 'yasnippet)
(yas/initialize)
Yasnippet 0.7.0 have already defined two locations for the snippets, "~/.emacs.d/yasnippet-install-path/yasnippet-x.y.z/snippets" and "~/.emacs.d/snippets". Yasnippet will load snippets in BOTH directories at startup.
So you only put your own snippets in "~/.emacs.d/snippets" and done. No need to tweak .emacs at all. To verify my claim, you can `C-h v yas/snippet-dirs' to check value of "yas/snippet-dirs". Please note "yas/root-directory" is the alias of "yas/snippet-dirs".
The real world setup is NOT simple
I will explain the reasons at first and give my complete yasnippet configuration code at the end of the this post.
Two snippets may share the same key, so I need activate `yas/dropdown-prompt'
One issue is I need a user-friendly dropdown window popped up when the key I input has several candidates. For example, when I type "inc" in C code. There are two candidates `#include "…"' and `#include <…>' available. A handy dropdown popup will help me to choose one of them as efficient as possible.
The good news is such fancy popup is a standard component of yasnippet. It's called `yas/dropdown-prompt'. Its default algorithm will activate it at highest priority.
The bad news is for some strange reason yasnippet won't load that dropdown-list by default. So you need manually load that component by one line of elisp code `(require 'dropdown-list)'.
`yas/dropdown-prompt' is not perfect
I cannot scroll down the dropdown window when there are more candidates it can display. That's especially annoying when calling `yas/insert-snippet'. In this case, we need use `yas/completing-prompt' instead. I will show the fix at the end of this article.
Yasnippet conflicts with other plugins
I use Auto Complete Mode (version 20120327 in elpa). There are two issues when using it with yasnippet.
First, it use TAB key to do the auto-complete thing while yasnippet also uses TAB key. So I need re-configure hotkeys of yasnippet.
Second, yasnippet changed its API `yas/get-snippet-tables' since version 0.7.0. This make the auto-complete cannot use yasnippet at all. This issue is reported and fixed by tkf. Actually all you need do is simple:
cd auto-complete-install-dir
rm auto-complete-config.elc
curl -L https://raw.github.com/tkf/auto-complete/337caa2ccc254a79f615bb2417f0d2fb9552b547/auto-complete-config.el > auto-complete-config.el
My final yasnippet setup
(require 'yasnippet)
(yas/initialize)
;; default TAB key is occupied by auto-complete
(global-set-key (kbd "C-c ; u") 'yas/expand)
;; default hotkey `C-c & C-s` is still valid
(global-set-key (kbd "C-c ; s") 'yas/insert-snippet)
;; give yas/dropdown-prompt in yas/prompt-functions a chance
(require 'dropdown-list)
;; use yas/completing-prompt when ONLY when `M-x yas/insert-snippet'
;; thanks to capitaomorte for providing the trick.
(defadvice yas/insert-snippet (around use-completing-prompt activate)
"Use `yas/completing-prompt' for `yas/prompt-functions' but only here..."
(let ((yas/prompt-functions '(yas/completing-prompt)))
ad-do-it))
在我的Mac OS X 10.7.3上为heroku开发rails程序
rails版本为3.1,OS X版本10.7.3,postgresql版本9.1.3j
数据库必须用postgresql
heroku官方主页反对开发版本用sqlite3而生产版本用postgresql.
在OS X 10.7.3上安装postgresql
首先,检查你的OS X版本,从10.7开始OS X自带postgresql
sw_vers -productVersion
如果要安装最新版的postgresql,必须删除老版本的数据库。具体做法参考这篇文章,实际上也就是一行命令:
curl http://nextmarvel.net/blog/downloads/fixBrewLionPostgres.sh | sh
强烈推荐用homebrew安装数据库,
brew install postgresql
具体安装细节请参考postgresql官方wiki.
检测已安装的postgresql
这里是一些数据库基本操作的官方文档. 可以`psql -l`看一些已有数据库列表.
数据库用postgresql的rails项目
rails new myapp --database=postgresql
如果是从一个已经使用sqlite的项目切换数据库,就必须改config/database.yml,有一些catch,请参考stackoverflow上的讨论.
然后,`createdb myapp_development`创建postgresql数据库,`rake db:migrate`建立数据库schema并导入数据在本地数据库.简单测试可证明数据库和web程序可以无缝工作.
最后不要忘记`git commit`最新代码.
部署web程序到heroku
请参考heroku官方文档,提醒一下不要忘记运行`heroku run rake db:migrate`,否则数据库是空的.
部署结束后可以运行`heroku open`打开浏览器访问web程序首页.
如打开网站有问题,可以`heroku logs`查看日志.
阅读了rails中使用bootstrap相关文章的小结
Luca Pette的Twitter Bootstrap on Rails比较简单,直接使用了bootstrap的css,没用less,测试了simple_form,show_for,kaminari(分页数据)三个应用。要点在于kaminari有点兼容性问题,用twitter-bootstrap-kaminari-views解决这个问题,其他没难度。
@metaskill的LESS Is More - Using Twitter's Bootstrap In The Rails 3.1 Asset Pipeline讲了如何用bootstrap的less函数和变量,我很有兴趣,根据我的经验能通过less语法调用twitter的函数比较有价值。安装gem `less-rails-bootstrap`就行了,调用bootstrap的函数的技术细节省略,基本就是less语法。
Adding Twitter's Bootstrap CSS to your Rails app的作者也读了以上两篇文章,要点在于确认了@metaskill的方法,less的一些详细的例子。也提到了可以用sass,但我没有深入读下去。
Twitter Bootstrap Basics at railscasts.com非常好,一个完整的例子。Comments也不错,一些html细节。要点在于用了gem`twitter-bootstrap-rails`,看起来很强大。
结论,看来我需要转向less而不是sass,因为bootstrap用less。