osx tips: 让Terminal和Finder互动起来
前提条件
首先,需要安装zsh,并开启osx插件。
强烈建议使用zsh为默认shell,并参考底部文章中使用oh-my-zsh。
Tips
从Terminal打开Finder
借助原生的open命令来做。
$ open .在Terminal中使用Finder的当前路径
# 显示Finder当前目录的ls列表 $ ls -al $(pfd) # 显示Finder选中文件的ls列表 $ ls -al $(pfs) # 转到Finder的当期目录 $ cdf
在Terminal中使用快速预览
$ quick-look 黑衣人.mkv快速将man命令内容格式化到pdf并打开
$ man-preview ifconfig
Terminal中讲文件移到回收站
$ trash 黑衣人.mkv相关链接
vim tips:快捷键被覆盖了怎么办
mswin.vim中实现了windows下的一部分快捷键兼容,包括Ctrl+C、Ctrl+V、Ctrl+S、Ctrl+A等等。
以Ctrl+A为例,一旦执行了mswin.vim,就找不到数字累加功能了。
这里提供一种手段来解决此类问题:
首先通过verbose来查看想要的快捷键在何处被绑定:
:verbose map <C-A> x <C-A> * <C-C>ggVG Last set from /usr/share/vim/vim73/mswin.vim s <C-A> * <C-C>gggH<C-O>G Last set from /usr/share/vim/vim73/mswin.vim o <C-A> * <C-C>gggH<C-O>G Last set from /usr/share/vim/vim73/mswin.vim n <C-A> * gggH<C-O>G Last set from /usr/share/vim/vim73/mswin.vim Press ENTER or type command to continue
可以通过这种方式取消这个绑定(使用默认方式):
:nunmap <C-a>
试试看,是不是Ctrl+A回来了?
然后知道了绑定位置后,在这绑定之前就可以做一个另外快捷键的绑定,这样就既都不会被破坏掉原始得配置,又可以使用想要的功能了:
nnoremap <C-a> <C-p> ... source $VIMRUNTIME/mswin.vim
vim tips: 终端中粘贴文本小技巧
在终端中使用文本粘贴,vim会当做串行文本输入来处理,会导致格式错乱,比如:
line1
line2
line3
...官方提供了一种模式是不会有自动缩进和自动注释的,使用方法如下:
:set paste
# do paste
:set nopaste在iTerm2中使用Zmodem的方法
iTerm通过trigger的方式可以使用sz、rz命令方便的通过Terminal在远程主机文件传输。
设置方法
首先需要安装iTerm Build 1.0.0.20120724以上版本,因为从这个版本开始支持trigger。
然后使用port安装sz、rz:
$ sudo port install lrzsz
通过链接中“iterm2-zmodem”的说明,分别把iterm2-recv-zmodem.sh、iterm2-send-zmodem.sh放到/usr/local/bin/下,并加上可执行权限。
这里需要做一点小改动,脚本本身需要执行mac的sz、rz,port安装后是在/opt/local/bin/下,而作者的是/usr/local/bin/下,这里需要手动修改一下。
这是修改后的:
iterm2-recv-zmodem.sh
#!/bin/bash # Author: Matt Mastracci (matthew@mastracci.com) # AppleScript from http://stackoverflow.com/questions/4309087/cancel-button-on-osascript-in-a-bash-script # licensed under cc-wiki with attribution required # Remainder of script public domain FILE=`osascript -e 'tell application "iTerm" to activate' -e 'tell application "iTerm" to set thefile to choose folder with prompt "Choose a folder to place received files in"' -e "do shell script (\"echo \"&(quoted form of POSIX path of thefile as Unicode text)&\"\")"` if [[ $FILE = "" ]]; then echo Cancelled. # Send ZModem cancel echo -e \\x18\\x18\\x18\\x18\\x18 echo \# Cancelled transfer echo else echo $FILE cd "$FILE" #/usr/local/bin/rz /opt/local/bin/rz echo \# Received $FILE echo fi
iterm2-send-zmodem.sh
#!/bin/bash # Author: Matt Mastracci (matthew@mastracci.com) # AppleScript from http://stackoverflow.com/questions/4309087/cancel-button-on-osascript-in-a-bash-script # licensed under cc-wiki with attribution required # Remainder of script public domain FILE=`osascript -e 'tell application "iTerm" to activate' -e 'tell application "iTerm" to set thefile to choose file with prompt "Choose a file to send"' -e "do shell script (\"echo \"&(quoted form of POSIX path of thefile as Unicode text)&\"\")"` if [[ $FILE = "" ]]; then echo Cancelled. # Send ZModem cancel echo -e \\x18\\x18\\x18\\x18\\x18 echo \# Cancelled transfer echo else echo $FILE #/usr/local/bin/sz "$FILE" /opt/local/bin/sz "$FILE" echo \# Received $FILE echo fi
修改iTerm2的default trigger(iTerm偏好设置-> Profiles -> Default -> Advanced -> Triggers的Edit按钮):
Regular expression: \*\*B0100 Action: Run Silent Coprocess Parameters: /usr/local/bin/iterm2-send-zmodem.sh Regular expression: \*\*B00000000000000 Action: Run Silent Coprocess Parameters: /usr/local/bin/iterm2-recv-zmodem.sh
相关链接
iTerm2下载:
http://code.google.com/p/iterm2/downloads/list
iTerm2 trigger说明:
http://www.iterm2.com/triggers.html#/section/home
iterm2-zmodem脚本:
https://github.com/mmastrac/iterm2-zmodem
关于Flask的默认session
Flask的默认session利用了Werkzeug的SecureCookie,把信息做序列化(pickle)后编码(base64),放到cookie里了。
过期时间是通过cookie的过期时间实现的。
为了防止cookie内容被篡改,session会自动打上一个叫session的hash串,这个串是经过session内容、SECRET_KEY计算出来的,看得出,这种设计虽然不能保证session里的内容不泄露,但至少防止了不被篡改。
另外,过期时间是这样来设置:
from datetime import timedelta session.permanent = True app.permanent_session_lifetime = timedelta(minutes=5) session['key'] = value
详情参见源码:
$PYTHONPATH/site-packages/flask/sessions.py
官方的Snippets给出了一则更好的客户端Session:
http://flask.pocoo.org/snippets/51/
sublime2试用手记
评价
总起来说是一款很牛X的编辑器,只是习惯了VIM的高效再去评判一些编辑器就总会带有一些“偏见”。
亮点
- 可以使用vim的基本快捷键,这样对于vimer切换到此环境有很大帮助。
- 打开大文件速度很快,与vim相差无几,但比vim更人性化的加入了进度条。
- 整体的UI设计非常赞,与gvim不在一个量级。
- 代码缩略图非常棒。
- 支持textmate形式的缩进,不过与vim的snippetmate相比,无优势。
- 支持Windows/Linux/Mac三大平台。
- 开发进度很快,势头很猛,值得期待。
- 具备多处同时编辑功能。
不爽
- 好多快捷键要改变习惯。
- 索引树没NerdTree好用。
- 又要用鼠标了。
- 不支持:命令,这个很是不爽。
使用方法
如何开启VIM模式
按下ctrl+shift+p -> 输入”settings user”
{
"ignored_packages": []
}
一个不错的入门教程:
http://lucifr.com/139225/sublime-text-2-tricks-and-tips/
一款git增强版工具legit
legit是什么
legit的灵感来自GitHub for Mac。 对branch操作做了很好的人性化设计。
主页在此:https://github.com/kennethreitz/legit
在README.rst中可以看到更详细的帮助。
用legit做分支操作
# 查看所有分支 $ legit branches * master (published) # 创建一个分支 $ legit sprout autocomplete Branching master to autocomplete. $ legit branches * autocomplete (unpublished) master (published) # 本地的分支需要通过publish与github同步 $ legit publish Publishing autocomplete. $ legit branches * autocomplete (published) master (published) # 删除一个分支 $ legit graft autocomplete Switching to master. Grafting autocomplete into master. Already up-to-date. Deleted branch autocomplete (was f0c3f4f). # 同步当前分支 $ legit sync Pulling commits from the server. Already up-to-date. Pushing commits to the server.
使用xinput来禁用触摸板(touchpad)
什么是xinput
xinput是操作输入设备(键盘、鼠标等)命令,同时具备输出设备列表、设置设备行为等功能。
使用man xinput来查看具体参数说明。
用xinput禁用touchpad
以我的Thinkpad X220为例,先列出所有input设备。
$ xinput --list ⎡ Virtual core pointer id=2 [master pointer (3)] ⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)] ⎜ ↳ Lenovo ThinkPad USB Laser Mouse id=10 [slave pointer (2)] ⎜ ↳ TPPS/2 IBM TrackPoint id=13 [slave pointer (2)] ⎜ ↳ SynPS/2 Synaptics TouchPad id=12 [slave pointer (2)] ⎣ Virtual core keyboard id=3 [master keyboard (2)] ↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)] ↳ Power Button id=6 [slave keyboard (3)] ↳ Video Bus id=7 [slave keyboard (3)] ↳ Sleep Button id=8 [slave keyboard (3)] ↳ Integrated Camera id=9 [slave keyboard (3)] ↳ AT Translated Set 2 keyboard id=11 [slave keyboard (3)] ↳ ThinkPad Extra Buttons id=14 [slave keyboard (3)]
找到了x220的touchpad id是12。
用以下方法禁用掉。
$ xinput set-int-prop 12 "Device Enabled" 8 0
最后的那个数字的“0/1”即为“禁用/启用”。
一个python的daemon类
通过此类可做到迅速将一个方法包装成daemon。
# -*- coding: utf-8 -*- # Daemon module # @auth jaypei # @email jaypei97159@gmail.com import sys, os, time, atexit, signal class Daemon(object): """A generic daemon class. Usage: subclass the daemon class and override the run() method.""" def __init__(self, pidfile, def_output=False): self.pidfile = pidfile self.def_output = def_output def daemonize(self): """Deamonize class. UNIX double fork mechanism.""" try: pid = os.fork() if pid > 0: # exit first parent sys.exit(0) except OSError, err: sys.stderr.write('fork #1 failed: %s\n' % str(err)) sys.exit(1) # decouple from parent environment os.chdir('/') os.setsid() os.umask(0) # do second fork try: pid = os.fork() if pid > 0: # exit from second parent sys.exit(0) except OSError, err: sys.stderr.write('fork #2 failed: %s\n' % str(err)) sys.exit(1) # redirect standard file descriptors if not self.def_output: sys.stdout.flush() sys.stderr.flush() si = open(os.devnull, 'r') so = open(os.devnull, 'a+') se = open(os.devnull, 'a+') os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) # write pidfile atexit.register(self.delpid) pid = str(os.getpid()) fp = open(self.pidfile,'w+') fp.write(pid + '\n') fp.close() def delpid(self): os.remove(self.pidfile) def start(self): """Start the daemon.""" # Check for a pidfile to see if the daemon already runs try: fp = open(self.pidfile,'r') pid = int(fp.read().strip()) fp.close() except IOError: pid = None if pid: message = "pidfile %s already exist. " + \ "Daemon already running?\n" sys.stderr.write(message % self.pidfile) sys.exit(1) # Start the daemon self.daemonize() self.run() def stop(self): """Stop the daemon.""" # Get the pid from the pidfile try: fp = open(self.pidfile,'r') pid = int(fp.read().strip()) fp.close() except IOError: pid = None if not pid: message = "pidfile %s does not exist. " + \ "Daemon not running?\n" sys.stderr.write(message % self.pidfile) return # not an error in a restart # Try killing the daemon process try: while 1: os.kill(pid, signal.SIGTERM) time.sleep(0.1) except OSError, err: e = str(err.args) if e.find("No such process") > 0: if os.path.exists(self.pidfile): os.remove(self.pidfile) else: print (str(err.args)) sys.exit(1) def restart(self): """Restart the daemon.""" self.stop() self.start() def run(self): """You should override this method when you subclass Daemon. It will be called after the process has been daemonized by start() or restart().""" raise NotImplementedError def doShell(self, argv): prog_name = argv[0] def usage(): print >>sys.stderr, "Usage: %(prog)s start|stop|restart" % { "prog": prog_name } sys.exit(0) if len(argv) != 2: usage() print command = argv[1] if command == "start": self.start() elif command == "stop": self.stop() elif command == "restart": self.restart() else: usage()
