Living with Vim

Preliminary

I started to write this document years ago, to illustrate Vim for some basic usage. The purpose was just trying to demonstrate how Vim could make your life easier. Recently, I decided to revise this document and to introduce more wonderful features. Some of them are new to Vim; some others are inherent but new to me. I am trying not to write a vast collection but a concise and effective one.

Vim is a very powerful editor to fulfill your goal efficiently. Using Vim directly is the best way to learn it. Did you learn to ride a bicycle by reading the user manual or some tutorial? So, do not expect that you can become a Vim expert by just sitting and reading any kind of documentation. Therefore this is not an exhaustive tutorial here. I am going to introduce how to take the advantage of Vim in your daily life, e.g., to make it more effective in writing your C/Perl/Python/Verilog/LaTeX, or any other documentation. In addition, the brand-new features in Vim 6 will be mentioned, since the new 6.1 release is stable now.

Part 0: Getting the Style

Vim is Not Vi

In FreeBSD, Vim is described as: ``A vi `work-alike', with many additional features''. In Linux, ``vim - Vi IMproved, a programmer's text editor''. Vim is an improvement over the editor, vi, one of the standard UNIX text editors. The creator is Bram Moolenaar. Vim adds many of the features that you would expect in an editor: Unlimited undo, syntax coloring, split windows, visual selection, graphical user interface, and much much more. Vim runs on many operating systems, including most UNIX/Linux systems, MacOS, DOS and Windows (95/98/NT4/2000/XP), etc. And the best of all: Vim is FREE! :-)

So why should I use a vi clone like Vim? Well, I realized the answer after starting to use Vim. Perhaps you should learn the answer by yourself. If you are looking for some visible reasons, try the article: ``What Vim Can Do?'' at < http://vim.sourceforge.net/about.php >.

The Convention

Some notations are used throughout the article to help the illustration. The notation C- denotes a Ctrl key combination for short. C-w represents the combination of Ctrl and w. C-w C-s and C-w-s are identical, holding Ctrl and w, keeping Ctrl held and then pressing s. On the other hand, C-w o denotes holding Ctrl and w, releasing Ctrl and then pressing o. Similarly, M- denotes a Meta or Alt key, and S- for Shift key. The arrow keys are represented as Up, Down, Left and Right. Other special keys will be self-explanatory, for example, Home, PageUp, F1, Esc or Enter, etc.

The Mode in the Editor

A text editor has to distinguish whether a user is going to key in the text content or to execute a command. A text editor such as joe or emacs accepts plain keys for normal input, and reserve keys combined with Ctrl, Alt for commands. Some other editors provide a dedicated command line to issue a command. For Vim, the philosophy is providing separate modes for different kinds of actions.

Formally, Vim has six basic operation modes: the Normal mode, Visual mode, Select mode, Insert mode, Command-line mode and Ex mode. In addition, there are five additional modes: the Operator-pending mode, Replace mode, Insert Normal mode, Insert Visual mode and Insert Select mode. Before scaring you, let's stop talking about these modes. We will discuss a few of them in the following when involved. Look to :help vim-modes for the details if you want to.

Getting the help

Perhaps the fastest way to get a help is asking some Vim seniors for your difficulties. However, Vim does provide user manual. When using GUI, getting the manual is straightforward by mouse clicks. The commands F1 or :help will bring you to the help. Additional references among the Internet are listed at the end of this article.

When in the help, move the cursor on some keyword (e.g., the word enclosed by a pair of |, ' or {}). You can jump to the help of the word just like accessing a hyperlink by C-], or back by C-t.

  C-] or C-LeftMouse     Jump to the tag
  C-t or C-RightMouse    Back to previous location

To seek for a specific topic, using :help keyword, such as

  :help insert

You can learn a lot from the documentation. The online help contains almost everything you need, so be patient to read the instructions for the effectiveness and efficiency.

Part 1: A Quick Go-Through

Starting Your Engine

To start up Vim, simply type

  vim microprocessor.v

under the UNIX shell prompt to edit the file microprocessor.v, or

  gvim microprocessor.v

to launch the GUI of Vim, gvim. You can edit multiple files and open multiple sub-windows, initially:

  vim -o *.v

The window will be split horizontally to display all of the files at the same time. Using Vim 6, you can also use

  vim -O *.v

to get similar result with vertical sub-windows. At first you can see that each line begins with a ~ to indicate an inexistent line. If you turn on the ruler by :set ru, you can see a pair of numbers indicates the current cursor position in (row, column).

Text Editing

Basically we only care about four operation modes in Vim: the Normal mode, Insert mode, Command-line mode and Visual mode, perhaps also the Replace mode. When starting up, Vim stays in the Normal mode and any input will be treated as a part of the command. To append/insert the characters into the file you must enter the Insert mode first by some certain commands. Another worth mention is that the same key could have different meanings under different operation modes.

Moving the Cursor and Changing the Text

To moving the cursor, you can use the keys h, j, k and l, or arrow keys in the Normal mode. Note that the arrow keys also work in the Insert and Replace modes.

  h or Left     : move to the left
  j or Down     : move down
  k or Up       : move up
  l or Right    : move to the right

These four keys (I mean h j k and l) are very convenient to use for your right hand, but many people doesn't like them. If this is true, you can simply use the arrow keys to move the cursor.

When the file size is getting bigger, you can use the hot key to scroll the page

  C-f or PageUp     : move a page forward
  C-b or PageDown   : move a page backward

You are suggested to get familiar with h j k l for cursor moving, because your wrists need not go back and forth to type the input and arrow keys. That's good for you. Similarly, mouse action is evil. Try using the keyboard commands to explore the power of Vim.

Usually we edit a code in C, Perl, Verilog or some kind of language. The compilers often report that what number of the code is wrong, e.g., line 25 has a syntax error. You can jump to line 25 by using 25G at the Normal mode. If only command G is used, the cursor will go to the end of the file (the last line).

  1G or C-Home  : go to the first line
  nG            : go to the n-th line
  G  or C-End   : go to the last line

Similarly you can jump within a line

  0 or Home     : jump to the beginning of the line
  $ or End      : jump to the end of the line

In addition, you can jump between the words by using w and e to go forward and backward, respectively.

Exiting Vim

To exit Vim, just use

  :q

You will be prompted for ``No write since last change (use ! to override)'' if no save command is executed. Save then quit using

  :wq

If you do not like the previous modification, force Vim to leave by

  :q!

without saving the changes. The command :wq is identical to :x (some people may prefer :ZZ). You can also use :w! to force a write. Usually ! can force an action for file access.

So that's all, to invoke Vim and leave. Now let's talk about the Command-line mode. The Command-line mode is entered from the Normal mode with one of the following keys: / ? : !. We have already seen one of them, the : key. After pressing :, you can observe a colon at the bottom of the window, followed the cursor waiting for your input. Type a one- or multiple-key command then press Enter can invoke the action and go back to the Normal mode. Again, you can use Up and Down to search for the previous commands; Left, Right, Del, Backspace, Home or End key to move the cursor; and Esc to abandon the command.

An example we have discussed is to turn on the ruler setting

  :set ruler

or

  :set ru

for short. Every setting or command has its abbreviation if no ambiguity. You can also save the settings you like into a startup file called .vimrc in your home directory ($HOME). The settings inside do not need the starting colon, i.e.,

  set ru

Additionally, many settings can be turned off by setting again with preceding no, e.g., :set noru. You can use :set to see your customized settings.

Part 2: The Advanced Skills

Undo/Redo Your Changes

To undo a change simply use u. Vim allows multiple undoes, therefore you can go back as many times as you want. Using C-r can redo an undo. Also you can do multiple redoes.

Copy and Paste

In Vim, the copy and paste commands are called as Yank and Put. The usage of yanking is very similar with deletion.

  yw: yank a word
  yy: yank a line

also 12yy will copy 12 lines into the buffer. The next step is to put (paste) the content to where you like. Move the cursor and use p to put the content (in the buffer). Moving a line or a word or multiple lines is simply deleting them then putting at the new location.

The visual blocking (or the Visual mode) is sometimes more satisfactory. Using V can enter the Visual mode from the Normal mode (Note the -- VISUAL LINE -- at the bottom). At the same time, you will see the current line is highlighting. By moving the cursor you can mark more lines. A d or y can delete or yank these highlighted lines. There are three different visual modes.

  V     : linewise visual mode      (prompting -- VISUAL LINE --)
  v     : characterwise visual mode (prompting -- VISUAL --)
  C-v   : blockwise visual mode     (prompting -- VISUAL BLOCK --)

Try to find their usefulness. The Visual mode can also be abandoned by Esc.

In visual mode there are many available operations, among them here are some common and useful ones:

  d     : delete
  y     : yank
  U     : uppercase all characters
  u     : lowercase all characters
  ~     : toggle case
  <     : unindent
  >     : indent
  o     : changing the start of a block

Note that in gvim, you can also use mouse to define a visual selection.

Read External Files

You can insert the content of an external text file under the cursor using the :r command by entering the Command-line mode:

  :r filename

Search and Replace

To search a pattern, use

  /pattern

This is another Command-line mode. When back to the Normal mode, you can use n to find the next match, or N for the previous match.

  ?pattern

can do the same thing, with opposite searching direction. Regular expression (regex) can be used for searching, however, I will not cover the details in this article.

When the ignorecase setting is on, pattern is searched case-insensitively, that is, by setting

  :set ic

When the smartcase option is set, :set scs, the search for /Intel and /intel are different, even when the ignorecase ic is on.

To search tall but not install, use

  /\<tall\>

to define the word boundary.

We have seen the Replace mode above. Sometimes we want to replace a keyword with another throughout the file. For example, if you want to replace every Intel with AMD, use

  :%s/Intel/AMD/g

The syntax format is

  :%s/oldpattern/newpattern/gcI

  %             : the range of the whole file
  s             : substitution
  oldpattern    : old pattern to match
  newpattern    : new pattern for replacement
  g             : global (optional)
  c             : confirm for every replacement (optional)
  I             : smart case (optional)

The first part indicates the range, % means the whole file, and you can define the range of part of the file, as

  :2,46/oldpattern/newpattern/gc

to apply the substitution from line 2 to line 46. Here are some definitions for the range:

  .     : current line
  $     : last line of the file
  %     : entire file

The second part indicates the command, s means substitution. The characters / separates two patterns for matching and replacement. The last field is for the options. Global option g is meant to match every pattern in one line, instead of the first matched pattern of the line. The option c will prompt every match to confirm the replacement.

The Visual mode can be used for substitution, e.g., you can mark multiple lines using V, then type : to enter the Command-line mode, a line will appear as

  :'<,'>

then append the substitution command s/oldpattern/newpattern/g.

Note that in searching and replacement, some characters have special meanings. For example, to search for /usr/local, use

  /\/usr\/local

because / defines the boundaries of the patterns. Similarly, the . in the searching pattern stands for any character and * means that the preceding character may occur zero or more times. Therefore, they have to be escaped by using \ if the plain key is needed. More details on regex expression can be found in ``Vim Regular Expression 101'' < http://physlab.sci.ccny.cuny.edu/~orycc/vim-regex.html >.

In the Normal mode, you can search for the word under the cursor by pressing * for the next matchings and # for the previous ones.

Auto-Wrapup and Reformatting

It is handy if the text editor can wrap around the input when reaching the predefined margin. First define a wrapmargin

  :set wrapmargin=15

or set the text width

  :set textwidth=65

These two settings above are equivalent for an 80-char-wide terminal. Remember that tw can override wm and they are both zero by the default. With your favorite margin, you can reformat a paragraph by marking a visual block and then typing gq, or mapping the command as

  :map Q gq

Another useful reformat command is J (join, in the Normal mode) which can join the current lines and the next line as one.

Location and File Status

Type C-g will report the filename with the status (modified or readonly), total number of lines and the cursor position.

Showing the Line Number

Someone prefers to precede each line with its line number when programming. This can be done by :set number or turned off by :set nonumber. The line number, however, takes some place and narrows down the window.

Editing Multiple Files

Editing two or more files at once is convenient. You can copy or move a block from one file to the other as you wish. There are different ways to achieve the goal.

Part 3: The Wisdoms of Survival

Recovery When Panic

When you edit an important file and suddenly there is a power outage. The entire system is shutdown before you can save your source. Don't be sad because Vim provide a recovering mechanism. Checking a file called .microprocessor.v.swp if you are editing microprocessor.v. Recover your file using Vim

  vim -r microprocessor.v

or

  vim -r .microprocessor.v.swp

or just

  vim -r

and see if Vim can recognize the file to recover. Save it if everything is OK:

  :w! microprocessor.v

then remember to remove the swap file .microprocessor.v.swp.

Keyword Matching

If you are lazy as me, you will find this function wonderful :-) In the Insert mode, you can type a few characters of a word, e.g., if there is a string alu_pipeline_register that has been typed previously, you may just type alu then C-p. Vim will find out the last word in the file starting with characters alu, if it is not what you want, you can re-type C-p again to match other candidates. Similarly, C-n can do that for finding the next matches. Therefore you do not worry about the mistyping of the long variables, or rare words. Remap the key

  map ,, <C-p>

helps me to access the feature.

Syntax Highlighting

In our environment, the option of syntax highlighting is set by default. Therefore you can use it without any change. This feature is very convenient for coding. Switch on and off the syntax highlighting by

  :syn on
  :syn off

With syntax highlighting, some typing errors such as unmatched parentheses can be indicated immediately.

Braces Matching

If the cursor is on an opening parenthesis { [ (, the command % will move the cursor to the matching closing } ] ) in the normal mode, and vice versa.

In addition, you can even match a keyword pair properly, for instance, begin/end pair in Verilog file, by using the matchit macro. Load the script by

  source $VIMRUNTIME/macros/matchit.vim

before editing your file and that's all. Many languages are supported currently.

Insert or Delete an Indent

The key C-t or C-d can insert or delete an indent in the current line, no matter what column the cursor is, under the Insert mode. There are handy hot keys when you are editing language with ambiguous block boundary such as Python, which you have to insert or delete the indent yourself when necessary (Vim 6 can handle indention for Python). In addition, you can change the indention of a block. Mark a block in the Visual mode, then typing > to insert an indent, or < to delete one. If multiple indentions are needed, you can take the advantage of repeat command . to repeat the last action.

Settings for .vimrc

Some useful settings and mappings for .vimrc are listed as follows:

  set nocp      " nocompatible with vi
                " source some fancy settings
  source $VIMRUNTIME/vimrc_example.vim
  set sw=4      " shiftwidth
  set et        " expandtab
  set wm=8      " wrapmargin
  set bs=2      " backspace
  set ru        " ruler
  set ic        " ignorecase
  set is        " incsearch
  set scs       " smartcase: override the 'ic' when searching
                "     if search pattern contains uppercase char
  set vb t_vb=  " set visual bell and disable screen flash
  set backup    " enable backup and define the backup file
  set backupext=.bak
  set hlsearch  " hlsearch
                " allow backspacing over everything in
                " the insert mode
  set backspace=indent,eol,start

Use :help option-list for detail description of these options.

  map Q gq      " reformatting
  map ,, <C-p>  " map the auto-complete command to
                " a handy ,, sequence
  map \   %     " for parenthesis matching

  source $VIMRUNTIME/macros/matchit.vim

You can check the setting under the Command-line mode. For example,

  :set sw

or simply :set to list all the customized settings. Similarly, :map shows all the mapping and :let shows all the variables.

Toggle a Setting

Each time when you search a pattern, the matched words will be highlighted if the highlight search is set

  :set hlsearch

That is a little annoying if the screen is full of highlights. It can be turned off temporarily by :nohls. The highlights will be turned off and activated again for the next search automatically. Map this to a function key:

  :map <F8> :nohls<CR>

to disable the highlight search by :nohlsearch or :nohls for short.

In UNIX systems, you can copy and paste a whole paragraph by marking the text with mouse and pasting with middle button of mouse, between terminals. It is better to turn off the formatting capability of Vim such as auto-indention and to keep the original format when pasting. This can be done by :set paste, copying the text and returning the original status with :set nopaste. To speed up the switching on and off, use a map

  :map <F9> :set paste!<bar>set paste?<CR>

to toggle the setting. The <bar> is identical to |, which is a separator between commands.

Conditional Setting Skills

Some settings are various when editing different kinds of files. For example, you may want to map the following shortcut for LaTeX file.

  autocmd FileType  map! ,b \begin{}<Esc>i

There are several ways to achieve the same goal. Here is another one.

  "   for verilog syntax highlight
  :au BufReadPost * if exists("b:current_syntax")
  :au BufReadPost *   if b:current_syntax == "verilog"
  :au BufReadPost *     set sw=4
  :au BufReadPost *     syntax on
  :au BufReadPost *   endif
  :au BufReadPost * endif

The X Files: Trust No One!

Vim can encrypt your file by using <PRE> :X </PRE> . You will be prompted to enter the secret key. The encrypted text cannot be read without the right key so make sure there is no typo. It is common that mis-typing a :X when you really want to type :x to save and quit Vim (the same as :wq). Use Esc to cancel the action when prompting the encryption key if you don't want to continue.

Command Windows

Vim provides a good feature similar to GNU readline, i.e., you can recall the historical commands in the command prompt (when typing :) or search prompt (when typing / or ?) by using up arrow and down arrow keys. In addition, you can split a separate command window, by q: or q/, respectively.

Living with Others

You can execute a command using the external shell, for example,

    :!ls

can simply list the file of current directory without leaving your text editor.

    :r !date

can insert the output, the time stamp, of date command. To compile you C code when editing it, :!gcc kernel.c, or :!gcc % to compile the current editing file. Note that % represents the current buffer you edit, i.e., current file. For the mapping

  map ;l  :w<CR>:!latex %<CR>

typing ;l will save the current Tex file and compile it using latex. If you have a Makefile for your program, simply

  :make

can do the compilation. Open an error window

  :copen

The errors will be prompted in the error window and you can jump to the error location by moving the cursor to the error and hit the Enter.

Filtering Your File*

How about reformatting your legacy code by Vim's new indent feature? Firstly, open an existing code, the type gg=G. The first gg moves the cursor to the first line, the = executes the indent function, where the last G indicates that the motion is applied to the end of the file.

In addition, the = can do more. For example, you can create an external filter, such as

  %cat add_number.pl
  #! /usr/bin/env perl
  my $i = 1;
  while (<>) {
    printf "%3d: %s", $i++, $_;
  }

Then, define the Perl script in your Vim,

  set equalprg=add_number.pl

Use the gg=G again, you can see that each line is attached a line number. Also you can filter a block by the visual blocking command.

Key Mapping

For a daily work, mapping is useful to replace a long command or text sequence with a short one. For example,

  map! ,b \begin{}<Esc>i
  map! ,e \end{}<Esc>i
  map! ,i \begin{itemize}<Return>\end{itemize}<ESC>O\item 
  map! ,f \begin{figure}<Return>\end{figure}<ESC>O

could be some useful mapping for editing LaTeX file in the Insert mode (note that they also apply to the Command-line mode). The use of :unmap ,b can remove the mapping.

Control of the Diversity

Some settings are suitable for specified application but not for others. For example, the mapping for LaTeX is no good for Verilog.

  autocmd FileType tex   map! ,b \begin{}<ESC>i

This autocommand only maps ,b when dealing a tex file.

Spelling Check

Spelling check is an important action. In our UNIX platform, ispell is used for the spelling check. Under the text mode, calling ispell is easy, use the mapping

  map ;s  :w<CR>:!ispell -x -t %<CR>:e<CR>

The command ;s will enter the interactive mode of ispell. Note that -t option of ispell is for LaTeX file. For gvim, the interactive mode causes a mess. Using another alternative

  map ;i  :w<CR>:!rxvt -e ispell -x -t %<CR>:e %<CR><CR>

can popup an rxvt clone for the interactive spelling check, and return to gvim when finished. There are some solutions to check and correct the spelling under gvim. Check these sites:

  http://www.fleiner.com/vim/
  http://www.irendi.com/vim/
  http://users.erols.com/astronaut/vim/

Living with MS Windows

After you are familiar with Vim and becoming a monomania, you are going to install Vim on every machine you use. Vim for MS Windows is a handy tool on your Windows platform. For Vim 6, a self-installing is provided (something like gvim61.exe). Just follow the installation wizard and you will get everything. For Vim 5.x, a gvim#old.zip and a vim#rt.zip are needed, where # denotes the version number. All you have to do is uncompressing the files into the same directory and run the install.exe. (However, no reason to use the older release.) For windows version, you can right-click any files inside the file explorer, choose the item ``Edit with Vim'' in the popup menu. You can also change the file association to invoke gvim.

Converting between DOS and UNIX format

It usually happens when moving the files from DOS/Windows system to UNIX. Each end of line sometimes gets additional C-m and causes error when processed by some applications. This is a good old practice to convert files from DOS format to UNIX one.

  1. Edit the file using binary mode

      vim -b dos_format.txt
    

    The extra characters will appear at the end of lines.

  2. Remove the characters by searching and replacement

      :%s/^M$//
    

    There are several tips here:

    1. The command can be abbreviated to :%s/^M$

    2. ^M is obtained by pressing C-v C-m in the Command-line mode (also the Insert mode). The key combination is the same as <C-M>

    3. The character $ is a regex pattern to match the end of line with zero width. Similarly ^ can be used to match the start of line. For example,

        /^function
      

      search for lines starting with the word function.

However, this is the old-style solution. With today's Vim, open the file normally, observe the format by :set fileformat. If the format is dos, change it by :set fileformat=unix. After all, save the file and exit. That's all.

Part 4: Vim for Your Brand-New Life

Vim has introduced the latest stable release, Vim 6.x. Some of the brand-new features are discussed as follows.

Auto-indention for Any Language

The original Vim can handle the indention of C-style language automatically. The new Vim, moreover, has the ability to auto-indent any language. Currently, the supported languages includes HTML, Java, Perl, Python, sh, Tcl, Verilog and more. Once you edit the file, you will get the ability of indention. Please let me know if there is any suggestion for Verilog indention style.

Vertical Splitting

Similar to C-w s, use C-w v (or :vsplit filename) to split vertically. The vertical splitting facilitates line by line comparison, such as diff function.

Diff Function

The diff function can be used when startup with vertical splitting

  vim -d arm.c arm.orig.c

Or using horizontal splitting

  vim -od arm.c arm.orig.c

The differences will be marked by highlights. Note that parts of the content will be folded. You can unfold and refold by clicking the + or - symbols in gvim, or using the commands

  zo    open the fold under the cursor
  zc    close the fold under the cursor
  zO    open all folds under the cursor recursively
  zC    close all folds under the cursor recursively
  zM    close all folds
  zR    open all folds

Sometimes diff will be out of date, use :diffu to update the comparison.

Abbreviation

Abbreviation :abbreviate is somewhat different with mapping. It applies to the Insert mode, Replace mode and Command-line mode. Sometimes it is useful for simple spelling check:

  :ab teh the
  :iab fo of
  :iab ot to
  :iab tihs this
  :iab ct Chih-Tsun Huang

where :iab restricts the usage in the Insert mode.

Color Schemes

Several pre-defined color schemes are available to choose. You can pick one easily through the pulldown menu of gvim.

Folding*

Folding can be used in diff mode. Please refer to ``Diff Function'' to the key binding. In addition, folding will help programming to keep the code concise. For example, you can fold all other function blocks while editing a specified one. There are six fold methods. Some are introduced here.

Marker Method

The content of functions is hidden so they are not annoying. For example,

  set foldmethod=marker
  set foldmarker=module,endmodule

will fold up the module blocks in Verilog.

Manual Method

Similarly, set the fold method to enter the manual mode,

  set foldmethod=manual

Then you can fold/unfold any parenthesis block by moving the cursor to one of the parenthesis and pressing zf%. Note that the % key is to find the matched parenthesis.

Syntax Method

To set folding for C-style language, use the following settings:

  au BufReadPost *.c    syn region myFold start="{" end="}" transparent fold
  au BufReadPost *.c    syn sync fromstart
  au BufReadPost *.c    set foldmethod=syntax
  set foldlevel=0

This will make each {} block to form one fold. However, using syntax folding will slow down the startup of Vim, especially for a large file. Setting fold level to 0 makes each parenthesis block to be folded at the startup. Or you can set the fold level to 99 to unfold each block initially (:set foldlevel=99). See :help syn-fold for the details.

Indent Method

This method might help for language like Python. Use

  set foldmethod=indent

Folding Tips

See :help folding for further features.

Part $: References

There is an official website for Vim < http://www.vim.org >. Many other people are also generous in showing their experience of Vim. Some references have been mentioned throughout this article, they are not listed again. Actually, many parts of this document are composite from borrowing someone else's ideas. Please visit my website for a detailed list of references:

  http://larc.ee.nthu.edu.tw/~cthuang/vim/
Last Modified @ Mon Aug 19 10:49:49 2002 by cthuang
Email: cthuang@larc.ee.nthu.edu.tw
URL: http://larc.ee.nthu.edu.tw/~cthuang/