Showing posts with label Vim. Show all posts
Showing posts with label Vim. Show all posts

Thursday, June 23, 2011

Gocode——用于Go语言的自动补全工具

原文发表于「桃源」: http://linux.cuit.edu.cn/?p=1362

一直以来, 我不太习惯于使用自动补全, 一是没有发现合适的 (这方面VS和Xcode这些IDE明显做得更好), 二来也觉得自己敲还来得快一点 (=_,=). 前几天发现 Gocode, 试用下来感觉还不错, 配置也不算繁琐, 推荐给使用Go语言的同学.

Gocode

Gocode现在支持的编辑器有Vim和Emacs, 分别利用Vim的omni completion和Emacs的 Auto Complete Mode. 想看实际演示效果的同学可以点 这里. 这里主要讲一下安装和Emacs的配置, Vim的配置由于比较简单, 可以参考 官方文档.

很多同学在安装Gocode的时候都会出现编译错误, 这主要是因为Go语言发展比较迅速, 这个星期的版本和上个星期的版本之间都可能存在不兼容, 默认 clone 下来的Gocode代码都是兼容最新版Go语言的 (这作者真勤劳), 因此如果你的Go编译器版本太陈旧的话就可能编译失败. 比如我电脑上的Go版本是 r57.1 (weekly.2011-05-03), 是一个release版, 而最新的Gocode是针对weekly.2011-06-16的, 这是一个开发者版. 理所当然的, 我在编译的时候遇到了编译错误, 这时我有两种选择, 要么升级Go, 要么降级Gocode. 升级Go对于我来说不太方便, 因为我的Go版本都是随着软件仓库一起更新的, 因此我选择了降级Gocode. 还好Gocode的作者给那些存在兼容问题的版本都打上了tag, 我们只需找到兼容自己电脑上当前Go版本的tag, 再回滚就行了.

$ git log --decorate
$ git checkout compatible-with-go-weekly.2011-04-27

接下来是编译和安装.

$ gomake
$ sudo gomake install

编译完成之后会生成 gocode 命令, 默认情况下 gomake install 会将 gocode 放到 GOBIN 环境变量指定的目录, 如果你没有设置 GOBIN, 那就会放到 ${GOROOT}/bin 里. 必须确保 gocode 命令可以在 PATH 环境变量中找到.

最后是配置Emacs. 首先你需要安装 Auto Complete Mode 扩展, 安装步骤可以参考 这里. 然后将Gocode提供的Emacs Lisp文件放到Emacs的 load-path 里即可. 注意这里使用到的el文件需要是最新版的 (非回滚版), 否则补全将失败.

现在用Emacs打开一个Go源文件试试看吧~

Sunday, January 23, 2011

解决Mac中Emacs、MacVim不能正确读取PATH的问题

发现我现在的题目真是越来越长了, 越来越有论文开题的范了~

因为安装了MacPort, 我在 “.bashrc” 文件中自定义了 PATH 变量, 但当我打开 “Emacs.app” 时却发现 PATH 变量并没有被正确读取, 最明显的表现就是会找不到我用MacPort安装的程序. 经过一番查找才 发现, 原来是因为Mac OS X中的GUI程序在启动时并不鸟Shell初始化文件, 管你 bash, tcsh, 什么 sh. 在Mac中有一个专门给GUI程序 设置环境变量的地方: ~/.MaxOSX/environment.plist, 这是一个二进制文件, 你可以使用Xcode自带的 “Property List Editor.app” 来查看、修改其中的内容, Mac中还有一个命令 defaults 也可以对这种类型的文件进行读写. 我们可以稍微修改一下 “.bashrc” 文件以便每次自定义好 PATH 变量之后就立即修改 “environment.plist” 文件, 代码如下:

export PATH=...
defaults write ~/.MacOSX/environment PATH "$PATH"

这样当再次打开 “Emacs.app” 时查看到的 PATH 变量就是正确的值了. 同样我在使用 “MacVim.app” 时也遇到了这样的情况, 我本来以为通过上面的方法已经解决, 但… 你懂的, 再次经过一番查找, 很多人也只是推荐上面的方法. 还有 勾选MacVim的 “Preferences” 中的 “Launch Vim processes in a login shell.”, 但在我的MacVim中没有找到这个选项, 应该是新版本取消掉了. 我怀疑这是MacVim的bug (不然为啥 “Emacs.app” 好好的…), 不过貌似也不是所有人都有遇到. 而我现在找到的唯一解决办法是直接从Terminal中执行 “mvim” 命令来启动MacVim, 这样就会继承Shell的环境变量, 不过这也是不得已才想出的临时解决办法, 毕竟我以后就不能直接用Quicksilver来启动MacVim了, 真是遗憾.

综上, Mac的App真够折腾.

Monday, April 27, 2009

近期的一些杂感

由于这几周都在忙着做事, 有好几篇blog想发却一直搁置着, 今天就把它们都写到一起吧.

先说攻防吧, 最近又出新题了还没去看, 对于注入这种层次的题目暂时不想了, 其它的什么编程题还能应付下, 无奈比例不大, 不能让队伍再靠前一点. 因为某题需要用到PHP的编程, 于是在重拾Emacs时发现默认是不支持PHP的高亮的, 这种事情肯定有人想到并解决了的, 安装php-mode就行了, Ubuntu可以直接apt-get install php-mode, 也可以自己到SF上去下载, 然后修改.emacs:
;; PHP mode for Emacs.
(require 'php-mode)
(add-hook 'php-mode-user-hook 'turn-on-font-lock)

以前的文章[参加三叶草Linux方向考核的一些总结]中介绍了一个叫做template的Emacs插件, 可以实现新建特定扩展名的文件时自动加载模板的功能, 像现在的某些IDE一样. SHE同学前段时间因为用Vim写汇编时必须重复地输入那些又长又难记的SEGMENT而苦恼, 问我Vim是否能自动加载模板. 查了一下, 还挺简单的, 这个不需要任何插件就能实现了. 修改.vimrc:
" Template for Vim.
autocmd BufNewFile *.asm 0r ~/.vim/templates/template.asm
注意中间那个是数字0, 而不是字母o. 把你的模板放在相应的文件里, 如果需要其它类型的模板修改扩展名就行了. 以上方法来自LinuxSir.Org.

由于最近需要经常测试网页, 愈发觉得用当前的Firefox调试很麻烦. 最让人痛苦的一点就是如果调试页面崩溃了, 还要连带影响我的正常浏览页面, 不得不一次又一次地重启. 实在是忍受不了之后 (看来我还是一个很能忍的人), 决定来一个专业一点的调试方法. 来自Mozilla的一篇文章:
Setting up an extension development environment
介绍了如何利用Firefox打造调试环境, 解决我前面那个问题的方法就是使用多用户配置文件, 实话说, 用了这么久Firefox还真不知道可以多用户运行的... 使用如下命令启动Firefox:
$ firefox -no-remote -P dev
这时应该会弹一个选择用户配置文件的窗口, 因为以前没有dev这个配置文件, 需要新建一个才行. 建好以后再用上面的命令运行的时候就会使用dev, 而不是默认的default了, 这样新开的浏览器与我之前打开的就不会相互影响了. 那篇文章还介绍了Firefox的一些配置调整以适应调试的需求和一些有用的调试插件, 这里强烈推荐Firebug, 看网页结构那叫一个爽.

最后, 那天看到一个很搞的命令: vrms. 为什么说它搞呢? 先看看这个缩写的全称吧: Virtual Richard M. Stallman. 那这个命令是用来干什么的呢? 号称可以找出你电脑上所有的非自由 (non-free) 软件, 晒下我的结果, ORZ... 内核也算?
                Non-free packages installed on LAN

fglrx-amdcccle Catalyst Control Center for the ATI graphics accelerat
fglrx-kernel-source Kernel module source for the ATI graphics accelerators
fglrx-modaliases Identifiers supported by the ATI graphics driver
human-icon-theme Human Icon theme
linux-generic Complete Generic Linux kernel
linux-restricted-modules- Non-free Linux 2.6.27 modules helper script
linux-restricted-modules- Restricted Linux modules for generic kernels
nvidia-173-modaliases Modaliases for the NVIDIA binary X.Org driver
nvidia-177-modaliases Modaliases for the NVIDIA binary X.Org driver
nvidia-71-modaliases Modaliases for the NVIDIA binary X.Org driver
nvidia-96-modaliases Modaliases for the NVIDIA binary X.Org driver
rar Archiver for .rar files
tangerine-icon-theme Tangerine Icon theme
tango-icon-theme Tango Icon theme
Reason: Creative Commons Attribution-ShareAlike 2.5 License
xorg-driver-fglrx Video driver for the ATI graphics accelerators

Contrib packages installed on LAN

msttcorefonts Installer for Microsoft TrueType core fonts
nvidia-common Find obsolete NVIDIA drivers

15 non-free packages, 0.9% of 1628 installed packages.
2 contrib packages, 0.1% of 1628 installed packages.

Wednesday, January 28, 2009

使用Vim的自动补全功能

前段时间SHE同学说想在Vim中有一个自动补全功能, 因为我以前都是不用这个的, 所以推荐他了一个在IRC上看到的命令: CTRL-N, 可这个命令使用之后列出的结果太多了, 花在找匹配上的时间还不如直接打呢.

昨天下午花了点时间研究了下, 开始还以为需要使用什么插件才能办到呢, 最后才发现其实Vim已经拥有了这些功能, 只是需要你去发掘.

Vim自带了很多种自动补全的方式, 最终选定了omni completion (全能补全), 如果想要查看其它的补全方式的话, 可以在Vim中输入 :help ins-completion

由于omni是借助tags文件来达到补全的, 所以需要安装有Ctags才行, Ubuntu可以用下面的命令安装:
$ sudo apt-get install exuberant-ctags

2009.12.26更新:
这里有一个针对C语言补全的小技巧, 在安装好Ctags之后, 可以先对系统中已有的头文件进行一次tag, 然后让Vim识别生成的tag文件 (下面的Vim配置文件中已经有相应的配置), 这样就可以实现对于C标准库函数以及system call的补全, Ubuntu下执行如下命令即可:
$ ctags -R -f ~/.vim/systags /usr/include

然后就是修改.vimrc文件, 下面是我已经写好了的, 添加进去就行了. 需要注意的是, 默认情况下omni completion的快捷键是CTRL-X CTRL-O, 但每次都这样有点麻烦, 所以我把这个快捷键映射到了<Tab>键上. 不过如果我只是想用<Tab>来增加缩进的话, 直接映射就会导致缩进功能消失了. 于是抄了一段Vim帮助中的脚本, 再根据实际情况修改了下, 这样就可以很智能地根据具体情况映射<Tab>键了. 如果这一行只有空白, 那么按<Tab>键就是增加缩进, 否则就是使用omni completion.
" ----------------------------------------------------------------------
" OMNI COMPLETION
" ----------------------------------------------------------------------

" Enable file type detection.
" Use the default filetype settings, so that mail gets 'tw' set to 72,
" 'cindent' is on in C files, etc.
" Also load indent files, to automatically do language-dependent indenting.
filetype plugin indent on

" Don't show the preview window.
set completeopt=menu

set tags+=~/.vim/systags,/tmp/tags

" Map <Tab> to either actually insert a <Tab> if
" the current line is currently only whitespace, or start a omni
" completion operation.
function! CleverTab()
    if strpart(getline('.'), 0, col('.')-1) =~ '^\s*$'
        return "\<Tab>"
    else
        let current_path = bufname("%")  " get name of current buffer
        let current_path = system("dirname " . current_path)
        execute "cd " . current_path
        execute "silent !ctags -R -f /tmp/tags ."
        return "\<C-X>\<C-O>"
    endif
endfunction
inoremap <Tab> <C-R>=CleverTab()<CR>

这是效果图:

omni completion

这时你可以使用CTRL-N或者CTRL-P来上下选择, 使用CTRL-Y来确定, CTRL-E来取消.

不过虽说这被叫做是全能补全, 但实际使用中还是有不是很顺利的地方的, 比如对于某些局部变量的补全. 这时可以试试CTRL-X CTRL-N, 将这两种补全结合着用, 应该就能满足日常需求了.

Saturday, December 6, 2008

关于使用ctags浏览代码的一些笔记

2010.11.22 10:20更新: 今天才发现我当初是没有弄清楚Vim寻找tags文件的方式, 现在看来, 只需要在源码根目录执行"ctags -R", 然后每次都使用这一个tags文件即可. 因此下面的做法相当于画蛇添足, 现仅留作存档.

2010.11.22凌晨更新: 下面的脚本中由于find用到了扩展的POSIX正则表达式, 因此请注意检查你系统中的find是否支持, 比如BSD系统自带的find就只支持标准的正则表达式.

昨天本来想看下xlockmore的源码的, 开始以为Vim + Tag List就差不多了, 后来发现不行的, 源码里面包含了一些include文件中的类型定义啊, 函数定义啊这些的, 想去看下原型都不行.

于是想到了ctags, 在我正在查看的源文件的目录下生成了一个tags文件. 这下好了, 可以跳转查看了, 不过马上新的麻烦又来了. 我还想在这个新跳转的文件中继续跳转, 但由于它同刚才的不在同一个目录, 所以Vim找不到相应的tags文件. 真是麻烦, 看来必须在每一个目录下都生成一个tags文件才行, 不过我很懒, 不想手动进入每一个目录, 然后重复执行那行命令. 查了一会儿ctags的man page, 没找到想要的功能, 又Google了一下, 还是没找到, 倒是找到了和我遇到相同麻烦的人, 呵呵~ 问了下joy, 貌似他也不是很清楚, 于是我就干脆写个脚本算了. 把这个脚本放在包含所有源码的根目录执行就行了.
#!/bin/bash

if which ctags > /dev/null; then
    echo "Hey, I get it!" > /dev/null
else
    echo "ctags is needed"
    exit 1
fi

base_dir=`pwd`
extension="\([cC]\|[cC][pP][pP]\|[hH]\)"

cd "$base_dir"
for dir in `find . -type d`; do
    cd "$dir"
    file=`find . -maxdepth 1 -regex ".*\.${extension}" -execdir echo 'found' \; -quit`
    if [ -n "$file" ]; then
        echo "$dir"
        ctags -R "$base_dir"
    fi
    cd "$base_dir"
done

exit 0
顺便记下在Vim中通过tags文件跳转的命令:
g^]  跳转
^T 跳回

然后还有个cscope, 可以用来搜索源码, 还没怎么用过.

P.S. xlockmore的源码看着真是费劲, n多的宏定义和typedef, 害得我头都看晕了...

Friday, August 15, 2008

Emacs和Vim中将tab转化为空格

Emacs:
在.emacs中添加:
(setq-default indent-tabs-mode nil)
对于已经保存好的文件, 可以选中需要转化的区域, 然后:
M-x untabify

Vim:
在.vimrc中添加:
set expandtab
对于已经保存好的文件, 可以选中需要转化的区域, 然后:
:retab

Monday, June 30, 2008

Vim的diff模式常用命令

:diffsplit {filename}
进入diff模式, 默认是水平分割, 但我比较喜欢垂直分割, 可以在.vimrc中添加set diffopt=vertical

[c & ]c
在差异的部分进行跳转

:diffget
用另一个缓冲区来修改当前缓冲区, 消除不同之处, 仅对光标所在行附近有影响

:diffput
用当前缓冲区来修改另一个缓冲区, 消除不同之处, 仅对光标所在行附近有影响

:diffupdate
刷新

Saturday, June 28, 2008

Vimfox

Vimperator

这几天在网上看很多大段的内容, 又懒得去碰鼠标的滚轮, 于是就想只依托键盘来滚动页面, 但那几个方向键按起来是非常得不爽, 滚动一点都不平滑, 再加上Vim也用习惯了, 就去整了这么一个插件.

好了, 现在向大家隆重推出史上最牛X的插件--Vimperator
使用甚是简单, 请参阅:help

Saturday, June 14, 2008

在Window$中使用Vim的taglist插件

1. 到这里下载ctags, 然后解压到任意非中文路径目录, 推荐根目录, 这样在后面修改_vimrc文件时也会方便些.
2. 在_vimrc文件中添加
let Tlist_Ctags_Cmd = 'D:\ctags\ctags.exe'
3. 下载taglist, 放到$VIM/vim71/plugin中.
4. 在Vim中输入:Tlist就可打开taglist.

不过我发现在Window$中不能使用taglist来浏览包含在中文路径中的源文件, 也不知这是为什么.

Tuesday, June 10, 2008

Vim 常用命令 (持续更新)

"+x
剪切

"+y
复制

"+gP
粘贴

:ls
列出缓冲区列表

:buffer #
打开相应缓冲区号中的文件

:bnext
:bprevious
:bfirst
:blast


:pwd
显示当前目录

:cd 目录名
改变当前目录

:e 文件名
在当前目录创建文件

:wa
保存所有已经命名的缓冲区

:e .
打开目录列表, 这个插件很神奇, 很强大, 这里有几个常用的命令:
- 访问目录的父目录
c 将你浏览的目录设为当前目录
R 为文件重命名
D 删除文件
d 建立新目录
<c-l> 刷新列表

在头文件上输入gf命令, Vim会寻找并打开文件, 如果该头文件不在此目录中, 则可以通过
:set path+=目录名
的方式添加需要查找的路径.

m{a-zA-Z}
在当前光标位置设置标记, 若是大写字母则是跨文件标记.

'{a-zA-Z}
跳转到相应标记的位置


'' 注意: 这是两个单引号
可以在两个最近的跳转位置中来回跳转

"xy
抽取选定文本到寄存器x

"xp
将寄存器x中的内容放到当前光标之后

:reg
显示所有编号和命名寄存器的内容

=
多行缩进

替换块
CTRL-V选定块后, 按c输入替换文本, 然后<Esc>

[[ & ]]
这会跳到上一个或是下一个在第一列的{, 如果你的代码风格是函数块开头的{都是单独占据一行的话, 那么这个命令就可以在所有函数块间跳转了.

gd
将光标放在某变量上, 可以使用这个命令跳转到定义该变量的位置.