Archive

Archive for the ‘随笔’ Category

Linux 网桥设置

December 8th, 2016 No comments

在公司机房的物理机上架设 KVM虚拟化的时候,经常需要配置网桥,先要安装网桥工具:

apt-get install bridge-utils   
apt-get install uml-utilities

编辑 /etc/network/interfaces,参考下面配置加入网桥配置信息:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet manual

auto br0
iface br0 inet static
    address 192.168.10.6
    netmask 255.255.255.0
    network 192.168.10.0
    broadcast 192.168.10.255
    dns-search dell1
    bridge_ports eth0
    bridge_stp off
    bridge_fd 0
    bridge_maxwait 0

auto eth1
iface eth1 inet manual

auto br1
iface br1 inet static
    address 14.152.50.6
    netmask 255.255.255.192
    network 14.152.50.0
    broadcast 14.152.50.63
    gateway 14.152.50.1
    bridge_ports eth1
    bridge_stp off
    bridge_fd 0
    bridge_maxwait 0
    # dns-* options are implemented by the resolvconf package, if installed
    dns-nameservers 114.114.114.114
    dns-search dell1

auto eth2
iface eth2 inet manual

auto br2
iface br2 inet static
    address 112.93.114.2
    netmask 255.255.255.224
    network 112.93.114.0
    broadcast 112.93.114.255
    gateway 112.93.114.1
    bridge_ports eth2
    bridge_stp off
    bridge_maxwait 0
    dns-nameservers 114.114.114.114
    dns-search dell1

上面配置针对双线接入多 IP的情况,这样 br0-br2就可以给虚拟机 guest使用了,br0是内网,br1-br2是电信或者联通出口。

Categories: 随笔 Tags:

Linux 硬件时区折腾备忘

December 8th, 2016 No comments

前段时间折腾家中 Nas的虚拟化服务,有时候虚拟机系统时间总是快8个小时。Guest这边设好了,到了 物理机就会慢8个小时。网上说只要修改/etc/default/rcS中的 UTC=no就行了,但还是没反映,没办法,一步步找问题。发现在/etc/rcS.d/S05hwclock.sh有这样一段话:

# 2012-02-16 Roger Leigh rleigh@debian.org
# - Use the UTC/LOCAL setting in /etc/adjtime rather than
# the UTC setting in /etc/default/rcS. Additionally
# source /etc/default/hwclock to permit configuration.

 
也就是说时间是按照/etc/adjtime设置的,而不是/etc/default/rcS,晕倒。查了下adjtime文件,原来这个才是现在调整时间的设置文件,那个rcS已经被忽略了,也就是网上的那些方法只适合以前的系统,看来走了不少弯路啊。

将 /etc/adjtime 第三行由 UTC 改为 LOCAL 即可。

Categories: 随笔 Tags:

Linux 线上系统调优备忘

December 8th, 2016 2 comments

大公司呆久了,都会对 SA的依赖十分强烈,很多事情 SA都帮我们搞定了。如今控制成本,没有招聘 SA,又没有购买 VPS,从买物理机开始到 IDC部署,服务器调优,虚拟机管理,全部都是自己来,才发现,安装一台 Linux机器自己玩很简单,但是要达到线上服务器的标准,还有若干调优工作需要做,有 SA的日志是多幸福的事情啊。

物理机设备驱动

Dell服务器默认安装系统后会报找不到驱动:

W: Possible missing firmware /lib/firmware/tigon/tg3_tso5.bin

因为 Debian/Ubuntu 的包都是开源的,默认开源驱动性能不行,于是需要添加 non-free源:

deb http://ftp.de.debian.org/debian main contrib non-free
deb-src http://ftp.de.debian.org/debian main contrib non-free

然后:

apt-get update
apt-get install firmware-linux-free firmware-linux-nonfree

解决 Dell驱动报错问题。

配置限制

查看 /etc/security/limits.conf 没有就新建,加入 core 和 nofile 的相关配置,比如:

* soft nofile 65536
* hard nofile 65536
* soft core unlimited
* hard core unlimited
# End of file

之类的,不用到 ~/.bashrc 里面调用 ulimit。

网卡多队列

打开内核网卡多队列支持,避免网卡中断都集中在 cpu0 上处理,多队列打开后,可以让网卡中断均摊到各个 cpu上,对提高并发十分有用:

wget http://skywind3000.github.io/install/set_irq_affinity.sh

放到 /etc/config 目录下面(没有就新建),然后在 /etc/rc.local 里面加一行,每次重启就跑 set_irq_affinity.sh 且必须用 bash跑,参数传入需要开启多队列的网卡,以下是 /etc/rc.local 的内容:

/bin/bash 
/etc/set_irq_affinity.sh eth0 eth1 eth2

exit 0

下面是 setirqaffinity.sh 的代码:

Read more…

Categories: 随笔 Tags:

Linux 下配置 Iptables 端口转发

December 8th, 2016 No comments

经常需要对服务端的端口进行转发映射,让链接A服务器(202.181.55.93:8080)端口的所有tcp数据,forward到B服务器(106.185.43.22:80)端口,比如国内联通出国访问比较快,而电信比较坑爹,如果你家是电信网络,你却想畅快的访问境外的 vps,那么可以在你联通网络的境内服务器上进行这样一个端口映射,你链接境内服务器(201.181.55.93:8080)端口相当于链接境外服务器的(106.185.43.22:80)端口。

Linux内核的 Iptables很强大,它维护一组内核变量,使用 /sbin/iptables命令进行直接规则设置,且通过配置新规则,可以直接支持端口转发,简单在 A服务器上使用下面这个 shell脚本即可:

#! /bin/sh

# create forward rule by source interface
# http://serverfault.com/questions/532569/how-to-do-port-forwarding-redirecting-on-debian
PortForward1() {
    local IN_IF=$1
    local IN_PORT=$2
    local OUT_IP=$3
    local OUT_PORT=$4
    local IPTBL="/sbin/iptables"
    echo "1" > /proc/sys/net/ipv4/ip_forward
    $IPTBL -A PREROUTING -t nat -i $IN_IF -p tcp --dport $IN_PORT -j DNAT --to-destination ${OUT_IP}:${OUT_PORT}
    $IPTBL -A FORWARD -p tcp -d $OUT_IP --dport $OUT_PORT -j ACCEPT
    $IPTBL -A POSTROUTING -t nat -j MASQUERADE
}

# create forward rule by source ip
# http://blog.csdn.net/zzhongcy/article/details/42738285
ForwardPort2() {
    local IN_IP=$1
    local IN_PORT=$2
    local OUT_IP=$3
    local OUT_PORT=$4
    local IPTBL="/sbin/iptables"
    echo "1" > /proc/sys/net/ipv4/ip_forward
    $IPTBL -t nat -A PREROUTING --dst $IN_IP -p tcp --dport $IN_PORT -j DNAT --to-destination ${OUT_IP}:${OUT_PORT}
    $IPTBL -t nat -A POSTROUTING --dst $OUT_IP -p tcp --dport $OUT_PORT -j SNAT --to-source $IN_IP
}

PortForward1 eth3 8080 106.185.43.22 80



# put this file on /etc/network/if-up.d

上面两个函数,一个是针对网卡,一个是针对本地IP设置转发,记得把这个脚本放到 /etc/network/if-up.d 下面并设置可执行权限(Debian/Ubuntu),每次开机重启时保证可以运行,即可。

Categories: 随笔 Tags:

Vim 里如何映射 CTRL-h 为 left ?

November 28th, 2016 No comments

很多人习惯在配置文件中映射 CTRL+HJKL 为光标移动,却碰到了一些问题:

inoremap <c-h> <left>
inoremap <c-j> <down>
inoremap <c-k> <up>
inoremap <c-l> <right>

映射后无效或者映射以后按 <BS>键不能删除,这是什么原因呢?

很简单,因为你的终端软件(Xshell, SecureCRT)有些老,默认配置是按下<BS>键以后
发送的是:^H (ASCII 码 0x08),而 ^H在你的 Vim 里被你 inoremap 成 了,所以你按了<BS>会被认为按下了左键。

早在 VT100终端时代,^H(ASCII码 0x08)表示<BS> 而 ^? (ASCII码 0x7f)表示<DEL>。过去 0x7f是留给 DELETE键使用的。而到了 VT220时代,DELETE已经变为 ^[[3~ (ASCII 码 0x1b, 0x5b, 0x33, 0x7e 共4个字节),而 ^? 的 0x7f 换给了我们的<BS>,有些老点版本的终端软件,默认 <BS>还是使用 VT100的 ^H,比如 Xshell 4 Build 0142以前的版本,默认<BS>是发送^H。SecureCRT直到6.x版本还在默认发送 VT100的 ^H。

你需要做的就是改一下终端默认配置而已,大部分不那么陈旧的终端软件,如今都是默认VT220的标准,比如 Xshell4 Build 0142及以后的 Xshell5,Putty,Mac下面的 Terminal.app, iTerm2,Ubuntu下面的 gnome-terminal,他们都是把 <BS> 发送成 ^?

你可以在你服务端下面查看下默认的键位设置:

$ stty -a

现在所有 Linux服务器的 erase (bs)基本都是 ^? 了(如果链接到非 Linux老操作系统 erase不是这个的话,需要改一下,可以在系统层改,也可以vim里面 set t_kb=…),Vim里面也是认可 ^?的,可老旧的终端软件却默认发送 ^H,不过好在他们都支持修改:

Read more…

Categories: 随笔 Tags:

Vim 中正确使用 Alt映射

November 19th, 2016 3 comments

最简单的做法是:首先将终端软件的 “使用 Alt键作为 Meta键” 的功能打开,其次将 Alt的模式改为 ESC+字母,意思是如果你在终端下按下 ALT+X,那么终端软件将会发送 <ESC>x 两个字节过去,字节码为:0x27, 0x78。如果你使用过 NeoVim 或者 Emacs的话,这一步应该早就做过了。

XShell4 终端设置:

SecureCRT:终端设置

其他终端软件里:

  • Putty/MinTTY 默认ALT+X 就是发送 <ESC>x过去
  • Mac下面的 iTerm2/Terminal.app 需要跟 XShell / SecureCRT一样设置一下
  • Ubuntu 下面的 GnomeTerminal 默认也是发送 <ESC>x过去的
  • 任意平台下面的 xterm 可以配置 ~/.Xdefaults 来设置这个行为。

这样的话,不管是 NeoVim 还是 Emacs都识别了,Vim 的话,你可以简单这样:

noremap <ESC>x :echo "ALT-X pressed"<cr>

注意 ESC后面是小写 x,如果你是大写 X就变成 ALT+SHIFT+X了。于是你在 Vim 中,ALT+X就能看到后面输出的那句话了。看到这里你也许要问:这和我快速按下 ESC再马上按下 x键有什么区别?答案是没有区别,在终端里面这两个操作是一模一样的键盘码传送过去。

就像你不设置 ttimeoutttimeoutlen,然后快速在 VIM 里面按下 <ESC>OP,Vim 会以为你按下了 <F1>一样。因为 F1 的终端下字符串序列就是 <ESC>OP ,而你在 Insert 模式下面马上 <ESC> 退出并按下大写 O ,向上插入一行,Vim 将会等待一秒钟(默认 timeout ),确认后面没有一个 P,才会进一步确认不是F1,而是向上插行。

所以更好的做法是直接按照 <M-x> 进行映射,并且告诉 vim,<M-x>的键盘序列码是多少,然后再加上 ttimeoutlen超时:

noremap <M-x> :echo "ALT-X pressed"<cr>
exec "set <M-x>=\ex"
set ttimeout ttimeoutlen=100

这样做的好处是告诉 Vim, ESC+x是一个完整的按键码,并且需要在 100ms以内进行判断,即,如果收到 ESC,并且100ms以后没有后续的x,则是认为是一个单独的ESC键,退出 INSERT模式,否则认为是按下了 ALT+X,这和 Vim处理方向键,处理 F1, F2等功能键的原则是相同的,具体见 :h set-termcap:

                            *:set-termcap* *E522*
For {option} the form "t_xx" may be used to set a terminal option.  This will
override the value from the termcap.  You can then use it in a mapping.  If
the "xx" part contains special characters, use the <t_xx> form: >
    :set <t_#4>=^[Ot
This can also be used to translate a special code for a normal key.  For
example, if Alt-b produces <Esc>b, use this: >
    :set <M-b>=^[b
(the ^[ is a real <Esc> here, use CTRL-V <Esc> to enter it)
The advantage over a mapping is that it works in all situations.

You can define any key codes, e.g.: >
    :set t_xy=^[foo;
There is no warning for using a name that isn't recognized.  You can map these
codes as you like: >
    :map <t_xy> something

这是最完善的 ALT键解决方案了,网上有个流传很广的方式是 map <ESC>x <M-x> 然后你后面再映射 <M-x> 时就能被触发到,这是错误的方法,不能使用更短的 ttimeoutlen来识别键盘码,而会使用普通组合键的 timeoutlen来判断,后者一般设置为默认 1000毫秒,所以这样把 26个字母映射后,你 ESC退出 INSERT模式后,一秒内按了任何一个字母就会被当成 ALT+X来处理了,经常误操作。

如此,我们可以在 .vimrc中 for循环将 <M-0><M-9><M-a><M-z>等全部 set一遍,vim中即可正常使用。

早年的终端,处理ALT组合键时,是将单个字符的最高位设置成 1,这也是 vim的默认处理方式,如今 rxvt终端也支持这种模式(见上图 SecureCRT设置面板)。这种键盘码不是 ESC+x的模式,可以直接识别,不需要计算超时,缺点是支持终端较少,对终端编码格式有依赖。

如今基本上 <ESC>+的模式基本成为大部分终端的默认方式,主流操作了,详细可以看::h map-alt-keys 以及 :h set-termcap 两个文档有具体说明,关于超时部分可以见(:h esckeys

当然,如果你真能在100ms内连续按下 ESC和 X的话,那是另外一回事情了,你可以调短 ttimeoutlen到50ms解决,但是不建议该值低于 25ms,否则在低速网络情况下,你按功能键会被vim错误识别成几个单独的按键序列。这不是 vim 的锅,而是终端标准的锅,ncurses 和 tmux 也都靠超时来检测功能键。

好了,帖一段代码吧:

function! Terminal_MetaMode(mode)
    set ttimeout
    if $TMUX != ''
        set ttimeoutlen=30
    elseif &ttimeoutlen > 80 || &ttimeoutlen <= 0
        set ttimeoutlen=80
    endif
    if has('nvim') || has('gui_running')
        return
    endif
    function! s:metacode(mode, key)
        if a:mode == 0
            exec "set <M-".a:key.">=\e".a:key
        else
            exec "set <M-".a:key.">=\e]{0}".a:key."~"
        endif
    endfunc
    for i in range(10)
        call s:metacode(a:mode, nr2char(char2nr('0') + i))
    endfor
    for i in range(26)
        call s:metacode(a:mode, nr2char(char2nr('a') + i))
        call s:metacode(a:mode, nr2char(char2nr('A') + i))
    endfor
    if a:mode != 0
        for c in [',', '.', '/', ';', '[', ']', '{', '}']
            call s:metacode(a:mode, c)
        endfor
        for c in ['?', ':', '-', '_']
            call s:metacode(a:mode, c)
        endfor
    else
        for c in [',', '.', '/', ';', '{', '}']
            call s:metacode(a:mode, c)
        endfor
        for c in ['?', ':', '-', '_']
            call s:metacode(a:mode, c)
        endfor
    endif
endfunc

command! -nargs=0 -bang VimMetaInit call Terminal_MetaMode(<bang>0)

使用::VimMetaInit 将会把 vim里面的键位码定义为 ESC+ 序列,而使用 :VimMetaInit! 则可以定义为更不容易混淆的:<ESC>]{0}x~ 格式(但是需要设置终端软件里每个ALT-x 组合键发送什么),将该代码放入你的 vimrc 文件中即可避免每次都调用。

Vim 默认的 ALT编码

比较一下 Vim默认的 ALT键识别方式(单字节高位设置1),比如 ALT+a,a的ascii码是 97,加上0x80以后值为 225,即发送一个 \u00e1 的 unicode字符过去,默认的vim就能识别成 ALT+a了,和 GVim的默认方式一样。看到这里你可能会问,为什么不把终端设置成 Vim的默认ALT编码,而是要弄一半天 <ESC>x 不当终端里面要设置,Vim里面也要重新设置一遍?默认方式 rxvt和 xterm等终端还不需要额外配置呢?这个方案好在哪里呢?

默认 ascii + 0x80的方式貌似省事,其实并不是,比如你想发送 unicode的 \u00e1 告诉 vim你按下了 ALT+a,那么你需要按照终端的字符编码格式来发送这个 unicode字符:比如你终端编码为 latin1的话,你只需要发送 0xe1 一个字节过去;而如果终端字符编码为 UTF-8的时候,你却需要发送 0xc3, 0xa1两个字节;GBK编码的话又要发送 0xa8, 0xa2两个完全不同的字节。

这就是一个问题,而我们使用 <ESC>的话,不管什么编码 <ESC> 都是 0x1b (27) 一个字节。再有一个问题是 iTerm2 之类的终端可以设置按下某键发送以 <ESC> 开头的字符串,却不能设置让你发送任意二进制,所以我们这个方式基本上是兼容所有终端的方式。

更友好的终端设置

上面在 SecureCRT / XShell 中设置了将 alt 键作为发送 +ESC x 的 meta 键后,你会发现,终端软件中固有的一些 ALT 组合键全部失效了,比如原来在终端中 ALT1 到 ALT9 可以切换终端的 TAB,ALT_B 可以打开链接管理器,这下都全部用不了了,这是件比较坑爹的事情,能不能保留有限的几个 ALT 组合键给终端软件使用,剩下的全部当作 meta 键呢?答案是可以的,先取消终端里 ALT 当作 meta 键的设置,恢复成默认状态,然后打开终端软件 keymap 设置窗口,将你不需要保留的 ALT 组合键全部设置成发送 +ESC x 字符串。

那么一个个设置可能有些麻烦,对于 SecureCRT 的话,我生成了一个配置文件:

A   VK_A                    "\033a"
A   VK_D                    "\033d"
A   VK_E                    "\033e"
A   VK_G                    "\033g"
A   VK_H                    "\033h"
....
AS  VK_A                    "\033A"
AS  VK_B                    "\033B"
AS  VK_C                    "\033C"
AS  VK_D                    "\033D"

可以到 这里 下载现成的,在 keymap editor 窗口中加载进去即可。

这份keymap配置除了保留了 SecureCRT 常用的 ALT1 – ALT9 ,ALTB, ALTR 和 ALTI 外,其他的 alt 组合都设置成了 +ESC x 的 meta 键序列。并且将 ALTSHIFT1 到 ALTSHIFT_9 映射到了终端里的 +ESC 1 到 +ESC 9 ,也就是说你的 ALT+数字 被保留给软件切换TAB用了,而 ALT+SHIFT+数字 被映射成了终端链接中的 ALT+数字,这样在终端里碰到需要 ALT+数字 的地方,可以用 ALT+SHIFT+数字 来代替。

设置好以后,你可以在终端下使用命令:

showkey -a

来查看自己的设置正确不,是不是按下 ALT_a 后正确发送了 0x1b, 0x61 两个字节过去了?

Categories: 随笔 Tags:

Vim 异步运行 Shell 指令的插件 – AsyncRun

August 24th, 2016 2 comments

自制另一个新的 Vim 8.0 专用异步插件:asyncrun.vim,它可以让你在 Vim 里面异步运行各种 Shell 指令并且把结果实时输出到 Quickfix,需要 Vim 7.4.1829 以上版本。

安装方法

到插件首页 https://github.com/skywind3000/asyncrun.vim 下载项目,并拷贝 asyncrun.vim 到你的 ~/.vim/plugin。或者使用 Vundle 指向 skywind3000/asyncrun.vim 来自动更新。

基本教程

使用 gcc 异步编译当前文件:

:AsyncRun gcc % -o %<
:AsyncRun g++ -O3 % -o %< -lpthread 

该命令会在后台运行 gcc 并且把输出实时显示在 Quickfix 窗口,宏 % 代表当前文件名,%< 代表没有扩展名的文件名。

异步运行 make:

:AsyncRun make
:AsyncRun make -f makefile

异步调用 grep:

:AsyncRun! grep -R word . 
:AsyncRun! grep -R <cword> .

默认 :AsyncRun 运行命令后,输出添加到 Quickfix时 Quickfix 会自动滚动到最下面那一行,使用感叹号修饰符以后,可以避免 Quickfix 自动滚动。同时 <cword> 代表当前光标下面的单词。

编译 go项目:

:AsyncRun go build %:p:h

%:p:h 代表当前文件的目录

查询 man page,异步 git push ,以及把设置 F7异步编译当前文件:

:AsyncRun! man -S 3:2:1 <cword> 
:AsyncRun git push origin master
:noremap <F7> :AsyncRun gcc % -o %< <cr> 

使用手册

AsyncRun – Run shell command:

:AsyncRun{!} [cmd] ...

后台运行命令并且实时输出到 quickfix 窗口,如果有感叹号修饰符,quickfix 窗口的自动滚动将会禁止。

命令参数以空格分割,接受下面这些以 ‘%‘, ‘#‘ or ‘<‘ 开头的替换宏:

%:p     - File name of current buffer with full path
%:t     - File name of current buffer without path
%:p:h   - File path of current buffer without file name
%:e     - File extension of current buffer
%:t:r   - File name of current buffer without path and extension
%       - File name relativize to current directory
%:h:.   - File path relativize to current directory
<cwd>   - Current working directory
<cword> - Current word under cursor
<cfile> - Current file name under cursor

运行一个命令前,环境变量也会做如下设置:

$VIM_FILEPATH  - File name of current buffer with full path
$VIM_FILENAME  - File name of current buffer without path
$VIM_FILEDIR   - Full path of current buffer without the file name
$VIM_FILEEXT   - File extension of current buffer
$VIM_FILENOEXT - File name of current buffer without path and extension
$VIM_CWD       - Current directory
$VIM_RELDIR    - File path relativize to current directory
$VIM_RELNAME   - File name relativize to current directory 
$VIM_CWORD     - Current word under cursor
$VIM_CFILE     - Current filename under cursor
$VIM_GUI       - Is running under gui ?
$VIM_VERSION   - Value of v:version
$VIM_MODE      - Execute via 0:!, 1:makeprg, 2:system()
$VIM_COLUMNS   - How many columns in vim's screen
$VIM_LINES     - How many lines in vim's screen

AsyncStop – Stop the running job:

:AsyncStop{!}

停止后台任务(使用 TERM信号),如果有感叹号修饰,则使用 KILL 信号结束

基本设置:

g:asyncrun_exit - 字符串,如果不为空那么任务结束时会被执行(VimScript)
g:asyncrun_bell - 如果非零的话,任务结束后会响铃(终端输出控制符 \a)
g:asyncrun_mode - 0:异步(需要 vim 7.4.1829) 1:同步 2:直接运行

全局变量:

g:asyncrun_code   - 退出码
g:asyncrun_status - 状态 'running', 'success' or 'failure'

如果你喜欢的话请为我投一票:
http://www.vim.org/scripts/script.php?script_id=5431

Categories: 随笔 Tags:

Vim 异步编译插件 vimmake

July 16th, 2016 1 comment

推荐下自己写的用了好几年的编程插件:vimmake ?完美支持 vim的异步模式:
GitHub – skywind3000/vimmake: Customize shell commands in vim

让用户自定义各种不同的编译或运行任务,并且在 Vim 中执行他们。类似 NotePad++的自定义 Commands 和 EditPlus/UltraEdit 的 ‘User Tool’ 或者 GEdit中的 External Tool 以及 TextMate 中的 Shell Command。完美支持 vim 7.4.1829 后已经稳定成熟的异步任务机制,不需要写任何 Vim Script 也可以很容易的体验到 vim 的异步任务机制,并且使用它来执行各种艰巨的编译任务,让你一边编辑代码,一边跑编译任务。

安装:拷贝 vimmake.vim 到你的 ~/.vim/plugin 或用 vundle 指向 skywind3000/vimmake .

简单使用:异步编译 & 运行 C/C++ 代码

首先每个 “用户自定义工具” 使用一个独立的 shell脚本来描述(Windows下是.cmd的批处理文件),我们将首先编写 vimmake可以使用的 gcc编译工具脚本, “~/.vim/vimmake.gcc”:

#! /bin/sh
gcc "$VIM_FILEPATH" -o "$VIM_FILEDIR/$VIM_FILENOEXT"

就这么短短的两行,当你把它设置成 0755的权限时,就可以在 Vim中通过下面语句运行了:

:VimTool gcc

命令 :VimTool {name} 命令会在 Vim里面直接调用 ~/.vim/ 目录下,名为 “vimmake.{name}” 的脚本来完成各种类似编译或者执行的任务,所以用:VimTool gcc 就可以运行前面定义的名为 vimmake.gcc 的工具脚本来编译当前的源代码了。

现在编辑 “~/.vim/” 下面名为 “vimmake.run” 的脚本,以便用 :VimTool run 来运行当前代码:

#! /bin/sh
"$VIM_FILEDIR/$VIM_FILENOEXT"

记得将 vimmake.run 的模式设置成 0755,如今有了两个可以直接在 Vim里通过 VimTool命令启动的工具(gcc 和 run),接下来我们需要设置 run 这个工具的模式为默认运行模式,而 gcc 为 quickfix模式(输出会被捕获并重定向到 quickfix窗口),现在打开 .vimrc 添加一行:

let g:vimmake_mode = { 'gcc':'quickfix', 'run':'normal' }

而如果我们能够使用到较新版本的 vim(7.4.1829或者更高),我们就可以使用异步方式在后台启动 gcc,并且将后台进程的输出实时重定向到界面下端的 quickfix 窗口:

let g:vimmake_mode = { 'gcc':'async', 'run':'normal' }

在这之后,将 ‘gcc’的运行模式设置成 ‘async’ 后,:VimTool gcc 就可以以异步的方式运行名为 vimmake.gcc 的脚本然后在后台执行编译任务了,就像传统 IDE编译任务一样。

以往使用 Vim 的 :make 之类的命令编译项目时,往往无法异步,编译任务一运行,你就无法编辑了,只有等到编译结束,才能返回编辑状态,大项目时,不得不另外开一个终端来进行编译,这是很痛苦的事情,有了异步任务以后,你能在同一个屏幕下编辑并且实时在 quickfix窗口查看编译的进度。

vimmake 可以让你在不需要掌握晦涩的 VimScript 和繁琐的异步编程接口的情况下,直接方便的使用vim 异步功能来完成各种长时间编译任务。同时为了加快你的:编译-编辑-编译 工作流的流畅度,我们需要配置一两个热键来调用 :VimTool 命令:

noremap <F7> :VimTool gcc<cr>
noremap <F5> :VimTool run<cr>
inoremap <F7> <ESC>:VimTool gcc<cr>
inoremap <F5> <ESC>:VimTool run<cr>

在 .vimrc里面加入上面的几行代码,你就可以方便的按 F7编译当前文件,F5运行之了。和GEdit
类似,VimTool命令在运行具体工具脚本前会设置若干环境变量来记录当前编辑的文件名,路径,当前vim工作目录等一系列信息,然后在工具脚本里面可以直接取出这些值来调用需要的外部工具链:
如上图,后台运行工具脚本进行编译,并且编译器的输出会被实时显示到下面的 quickfix窗口,选中错误的那行输出,会直接跳转:

Read more…

Categories: 随笔 Tags:
Wordpress Social Share Plugin powered by Ultimatelysocial