介紹一下在 C語言中 ++*p, *p++和 *++p的不同。

++*p

1
2
3
4
5
6
7
8
9
#include <stdio.h>

int main() {
int array[] = { 10, 20};
int *p = array;
int v = ++*p;
printf("v = %d, array[0] = %d, array[1] = %d, *p = %d\n", v, array[0], array[1], *p);
return 0;
}

*p++

1
2
3
4
5
6
7
8
9
#include <stdio.h>

int main() {
int array[] = { 10, 20};
int *p = array;
int v = *p++;
printf("v = %d, array[0] = %d, array[1] = %d, *p = %d\n", v, array[0], array[1], *p);
return 0;
}

*++p

1
2
3
4
5
6
7
8
9
#include <stdio.h>

int main() {
int array[] = { 10, 20};
int *p = array;
int v = *++p;
printf("v = %d, array[0] = %d, array[1] = %d, *p = %d\n", v, array[0], array[1], *p);
return 0;
}

++*p、***p++**和 *++p是由 postfix ++(++在後)、prefix ++(++在前)和 *(deference)運算子組合而成,其運算優先權與關聯性為:

  1. prefix ++與 *的運算優先權相同,關聯性為從右到左。
  2. postfix ++的運算優先權高於 prefix ++與 *,關聯性為從左到右。

++*p

因 prefix ++與 *的運算優先權相同,因此從右到左,可視為是 ++(*p),將指標 p取值後加 1,結果為 v = 11, array[0] = 11, array[1] = 20, *p = 11。

*p++

因 postfix ++的運算優先權高於 *,可視為是 *(p++),將指標 p加 1,因為是 postfix,所以取的值為指標 p加 1之前所指向的值,結果為 v = 10, array[0] = 10, array[1] = 20, *p = 20。

*++p

因 prefix ++與 *的運算優先權相同,因此從右到左,可視為是 *(++p),將指標 p加 1後取值,結果為 v = 20, array[0] = 10, array[1] = 20, *p = 20。

Note

遇到 postfix ++的情況,可視為在執行完 ; 之後,才會執行 ++的運算。

Reference

[1] C Operator Precedence Table

在 Shell programming中如何使用 if條件式。

if 條件式語法

使用 command exit status
if command
then
    command
    ...
else
    command
    ...
fi
使用 [ … ]
if [ condition ]
then
    command
    ...
else
    command
    ...
fi
使用 test command
if test condition
then
    command
    ...
else
    command
    ...
fi

if 比較運算子

字串比較運算子
[ … ] test command 用法(回傳 TRUE)
if [ string1 = string2 ] if test string1 = string2 string1與 string2相同
if [ string1 != string2 ] if test string1 != string2 string1與 string2不相同
if [ string ] if test string string 不為空值
if [ -n string ] if test -n string string 不為空值
if [ -z string ] if test -z string string 為空值
整數比較運算子
[ … ] test command 用法(回傳 True)
if [ int1 -eq int2 ] if test int1 -eq int2 int1等於 int2
if [ int1 -ne int2 ] if test int1 -ne int2 int1不等於 int2
if [ int1 -gt int2 ] if test int1 -gt int2 int1大於 int2
if [ int1 -ge int2 ] if test int1 -ge int2 int1大於等於 int2
if [ int1 -lt int2 ] if test int1 -lt int2 int1小於 int2
if [ int1 -le int2 ] if test int1 -le int2 int1小於等於 int2
檔案運算子
[ … ] test command 用法(回傳 True)
if [ -d file ] if test -d file file是個目錄
if [ -e file ] if test -e file file存在
if [ -f file ] if test -f file file是個檔案
if [ -r file ] if test -r file file可被讀取
if [ -s file ] if test -s file file內容非空
if [ -w file ] if test -w file file可被寫入
if [ -x file ] if test -x file file可被執行
if [ -L file ] if test -x file file是個符號連結
if [ -b file ] if test -b file file is a block special file
if [ -c file ] if test -c file file is a character special file
if [ -g file ] if test -g file file’s set group ID flag is set
if [ -h file ] if test -h file file is a symbolic link. This operator is retained for compatibility with previous versions of this program. Do not rely on its existence; use -L instead.
if [ -k file ] if test -k file file’s sticky bit is set
if [ -p file ] if test -p file file is a named pipe (FIFO)
if [ -u file ] if test -u file file’s set user ID flag is set
if [ -O file ] if test -O file file’s owner matches the effective user id of this process
if [ -G file ] if test -G file file’s group matches the effective group id of this process
if [ -S file ] if test -S file file is a socket
if [ file1 -nt file2 ] if test file1 -nt file2 file1比 file2新
if [ file1 -ot file2 ] if test file1 -ot file2 file2比 file2舊
if [ file1 -ef file2 ] if test file1 -ef file2 file1與 file2參照到相同檔案
邏輯負運算子 !

可使用 !來否定運算式的判斷,例如:[ ! -f file ]

邏輯 and運算子 -a

例如: [ -f file1 -a -f file2 ]

邏輯 or運算子 -o

例如: [ -f file1 -o -f file2 ]

括號的使用

例如: [ \( -f file1 \) -a \( -f file2 \) ]

這邊紀錄一下如何使用 GDB 對 LLVM(Low Level Virtual Machine) 進行偵錯,LLVM 前端為 Clang,若我們在下編譯參數時,希望 Clang 直接產生 object file 或是 executable file,Clang 在處理完前端資訊後,會接著驅動 opt(LLVM Optimizer) 進行優化,驅動 llc(LLVM static compiler) 產生目的碼,opt 與 llc 皆為獨立的程式,Clang 會呼叫起此兩個程式來進行剩餘的編譯工作,因此若將 break point 設在 opt 或 llc 所屬的程式碼時,會遇到無法停止的情況,本文紀錄如何解決此情況。

首先記得在編譯 LLVM 時,在 configure 加上 -DCMAKE_C_FLAGS="-O0 -g3"-DCMAKE_CXX_FLAGS="-O0 -g3",讓在編譯 LLVM 過程能夠加上 Debug information,可參考此篇如何編譯 LLVM 和 Clang 編譯 LLVM 與 Clang

寫個範例程式,讓我們能夠在編譯此範例程式的過程中,對編譯器偵錯。

1
2
3
4
int shift_and(int a) {
int b = a >> 12;
return b & 0xfff;
}

編譯此程式,並在過程中使用 GDB 來偵錯。

$ gdb --args ./llvm-build/bin/clang -O2 -c -o shift_and.o shift_and.c
GNU gdb (GDB) Fedora 7.12.1-48.fc25
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./llvm-build/bin/clang...done.
(gdb)

假設我們想要停在 lib/Target/AArch64/AArch64ISelDAGToDAG.cpp的2707行。

(gdb) b AArch64ISelDAGToDAG.cpp:2707
Breakpoint 1 at 0x1940ecd: file /home/users/jim/llvm/llvm-6.0.0.src/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp, line 2707.

讓程式開始執行,會發現因為使用 vfork 產生 child process的關係,gdb 此時無法針對產生出的 child process偵錯,會直接結束離開。

(gdb) run
Starting program: /home/users/jim/llvm/llvm-build/bin/clang -O2 -c -o shift_and.o shift_and.c
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.24-10.fc25.x86_64
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Detaching after vfork from child process 16302.
[Inferior 1 (process 16298) exited normally]
Missing separate debuginfos, use: dnf debuginfo-install libgcc-6.4.1-1.fc25.x86_64 libstdc++-6.4.1-1.fc25.x86_64 ncurses-libs-6.0-6.20160709.fc25.x86_64 zlib-1.2.8-10.fc24.x86_64

解決方法即為在執行程式之前,先設定好 set follow-fork-mode child,可看到順利地停在 AArch64ISelDAGToDAG.cpp:2707了。

$ gdb --args ./llvm-build/bin/clang -O2 -c -o shift_and.o shift_and.c
GNU gdb (GDB) Fedora 7.12.1-48.fc25
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./llvm-build/bin/clang...done.
(gdb) b AArch64ISelDAGToDAG.cpp:2707
Breakpoint 1 at 0x1940ecd: file /home/users/jim/llvm/llvm-6.0.0.src/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp, line 2707.
(gdb) set follow-fork-mode child
(gdb) run
Starting program: /home/users/jim/llvm/llvm-build/bin/clang -O2 -c -o shift_and.o shift_and.c
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.24-10.fc25.x86_64
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[New process 16732]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
process 16732 is executing new program: /home/users/jim/llvm/llvm-build/bin/clang-6.0
Missing separate debuginfos, use: dnf debuginfo-install libgcc-6.4.1-1.fc25.x86_64 libstdc++-6.4.1-1.fc25.x86_64 ncurses-libs-6.0-6.20160709.fc25.x86_64 zlib-1.2.8-10.fc24.x86_64
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[Switching to Thread 0x7ffff7fc5600 (LWP 16732)]

Thread 2.1 "clang-6.0" hit Breakpoint 1, (anonymous namespace)::AArch64DAGToDAGISel::Select (this=0x9fe0190, Node=0xa0923a0)
at /home/users/jim/llvm/llvm-6.0.0.src/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp:2707
2707        if (tryBitfieldExtractOp(Node))
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.24-10.fc25.x86_64 libgcc-6.4.1-1.fc25.x86_64 libstdc++-6.4.1-1.fc25.x86_64 ncurses-libs-6.0-6.20160709.fc25.x86_64 zlib-1.2.8-10.fc24.x86_64
(gdb)

本文介紹如何編譯 LLVM 與 Clang

先從 LLVM 官網(http://releases.llvm.org/download.html#6.0.0) 下載 Clang 與 LLVM source code,使用 LLVM 6.0.0

$ wget http://releases.llvm.org/6.0.0/llvm-6.0.0.src.tar.xz
$ wget http://releases.llvm.org/6.0.0/cfe-6.0.0.src.tar.xz

解壓縮

$ tar Jxvf llvm-6.0.0.src.tar.xz
$ tar Jxvf cfe-6.0.0.src.tar.xz

開一個新資料夾用來放編譯的東西

$ mkdir llvm-build && cd llvm-build

下 configure 指令

$ cmake -DCMAKE_INSTALL_PREFIX="../llvm-install" \
  -DLLVM_EXTERNAL_CLANG_SOURCE_DIR="../cfe-6.0.0.src" -DCMAKE_C_COMPILER=/bin/gcc \
  -DCMAKE_CXX_COMPILER=/bin/g++ -DLLVM_BUILD_EXAMPLES=False -DLLVM_PARALLEL_LINK_JOBS=2 \
  -DLLVM_DEFAULT_TARGET_TRIPLE=aarch64-unknown-elf -DLLVM_TARGETS_TO_BUILD=AArch64 -G \
  Ninja -DLLVM_ENABLE_ASSERTIONS=Yes -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS="-O0 -g3" \
  -DCMAKE_CXX_FLAGS="-O0 -g3" ../llvm-6.0.0.src

說明一下每個 configure 的功能

** DCMAKE_INSTALL_PREFIX **
指定 LLVM 安裝路徑
** DLLVM_EXTERNAL_CLANG_SOURCE_DIR **
指定 Clang source code 路徑
** DCMAKE_C_COMPILER **
指定使用到的 C compiler 路徑
** DCMAKE_CXX_COMPILER **
指定使用到的 C++ compiler 路徑
** DCMAKE_LLVM_EXAMPLES **
是否要編譯 example
** DLLVM_PARALLEL_LINK_JOBS **
設定平行連結的工作數量
** DLLVM_DEFAULT_TARGET_TRIPLE **
指定預設的 target triple,以 aarch64-unknown-elf來說,指定指令集架構為 aarch64,vendor 為 unknown,object file format 為 elf,當使用 clang 或 llc 時,沒有給予 -mtriple 此 option時,將會用此預設 target triple
** DLLVM_TARGETS_TO_BUILD **
指定要編譯哪一個 target,這邊指定要編譯 AArch64 此指令集架構,若沒有指定,則會將所有 target 給編譯起來,會相當耗時間
** -G Ninja **
指定編譯工具,這邊使用 ninja 編譯工具
** DLLVM_ENABLE_ASSERTIONS **
啟用 code assertion
** DCMAKE_C_FLAGS **
設定編譯 LLVM c code 的額外 flags,因之後有開發 LLVM 的偵錯需求,所以優化設定為 O0,即為不做任何優化,另外使用 g3,讓編譯出來的 LLVM 有 debug information
** DCMAKE_CXX_FLAGS **
設定編譯 LLVM c++ code 的額外 flags

最後指定 llvm source code 的路徑

開始編譯,-j30 為設定平行編譯個數,若所處硬體環境不強,可能需要耗時一個多小時以上才能夠編譯完成

$ ninja -j30

安裝到先前設定的安裝路徑

$ ninja install

順利的話應該可以在 llvm-install/bin 底下看到許多編好的工具

$ cd ..
$ ls llvm-install/bin/
$ bugpoint      clang-cpp              git-clang-format  llvm-cfi-verify  llvm-diff       llvm-lib         llvm-mt          llvm-ranlib   llvm-stress      sancov
  c-index-test  clang-format           llc               llvm-config      llvm-dis        llvm-link        llvm-nm          llvm-rc       llvm-strings     sanstats
  clang         clang-func-mapping     lli               llvm-cov         llvm-dlltool    llvm-lto         llvm-objcopy     llvm-readelf  llvm-symbolizer  scan-build
  clang++       clang-import-test      llvm-ar           llvm-c-test      llvm-dsymutil   llvm-lto2        llvm-objdump     llvm-readobj  llvm-tblgen      scan-view
  clang-6.0     clang-offload-bundler  llvm-as           llvm-cvtres      llvm-dwarfdump  llvm-mc          llvm-opt-report  llvm-rtdyld   llvm-xray        verify-uselistorder
  clang-check   clang-refactor         llvm-bcanalyzer   llvm-cxxdump     llvm-dwp        llvm-mcmarkup    llvm-pdbutil     llvm-size     obj2yaml         yaml2obj
  clang-cl      clang-rename           llvm-cat          llvm-cxxfilt     llvm-extract    llvm-modextract  llvm-profdata    llvm-split    opt

寫個範例程式,來測試一下編好的編譯器

1
2
3
int add(int a, int b) {
return a + b;
}

編譯程式

$ ./llvm-install/bin/clang -O2 -c -o add.o add.c

將程式反組譯,可看到 aarch64 的 assembly code

$ ./llvm-install/bin/llvm-objdump -d add.o
add.o:  file format ELF64-aarch64-little
Disassembly of section .text:
add:
    0:       20 00 00 0b     add     w0, w1, w0
    4:       c0 03 5f d6     ret

Reference

[1] Getting Started: Building and Running Clang
[2] Building LLVM with CMake

RISC-V 是一個開放指令集架構,任何人可基於此架構實作,基本指令長度為32-bit,設計成容易擴充與客製化的指令集架構,基本指令集架構大約只有一百多道指令,有32-bit(RV32),64-bit(RV64)和 128-bit(RV128)三種不同的暫存器長度,與模組化的擴充指令集。

RISC-V 指令集有以下四種基本指令集架構:

  • RV32I Base Integer Instruction Set
    32-bit 基本整數指令集,有 32個 32-bit暫存器。
  • RV32E Base Integer Instruction Set
    32-bit 嵌入式基本整數指令集,與 RV32I的差異為暫存器減少成只有 16個 32-bit暫存器。
  • RV64I Base Integer Instruction Set
    64-bit 基本整數指令集,有 32個 64-bit暫存器。
  • RV128I Base Integer Instruction Set
    128-bit 基本整數指令集,有 32個 128-bit暫存器。

標準擴充指令集(Standard Extension):

  • “M” Standard Extension for Integer Multiplication and Divison
    新增了整數乘法除法指令。
  • “A” Standard Extension for Atomic Instructions
    新增了 Atomic相關的指令。
  • “F” Standard Extension for Single-Precision Floating-Point
    新增了 32個 32-bit的 floating-point暫存器(f0-f31)與其相關的指令。
  • “D” Standard Extension for Double-Precision Floating-Point
    將 32個 floating-point暫存器(f0-f31)擴大成 64-bit與新增其相關的指令。
  • “Q” Standard Extension for Quard-Precision Floating-point
    將 32個 floating-point暫存器(f0-f31)擴大成 128-bit與新增其相關的指令。
  • “C” Standard Extension for Compressed Instruction
    新增了 16-bit長度的指令,用來替換掉常用到的 32-bit長度的指令,可減少 code size。
  • “G”
    為 I,M,A,F和D 的組合(IMAFD)。

還有一些已保留其名字,但尚未詳細制定指令的標準擴充指令集,例:”L”,”B”,”J”,”T”,”P”,”V” 和 “N”

可以把任一基本指令集加上一個或多個擴充指令集使用,例如:

  • RV32IMA
    即為 32-bit基本整數指令集加上整數乘法除法指令與 atomic相關指令。
  • RV64IMAFD
    即為 64-bit基本整數指令集加上整數乘法除法指令,atomic相關指令,single-precision與 Double-precision其 floating-point暫存器與其相關指令。

RISC-V 可自行新增指令集,為非標準擴充指令集(Non-Standard Extension),若想要在 RV32IMA之外新增某些指令稱為 “H”,則稱為 RV32IMAXH,接在 “X”之後的為非標準擴充指令集,RISC-V 提供了相當的彈性去選擇所需的標準擴充指令集,也可再加上自行客製化的非標準擴充指令集。

Reference

[1] The RISC-V Instruction Set Manual

本文介紹如何編譯 GCC toolchain

  1. 更新與升級系統
1
2
$ sudo apt-get upgrade
$ sudo apt-get update
  1. 安裝一下預設的 GCC toolchain,待會用來編譯 GCC toolchain
1
$ sudo apt-get build-essential
  1. 下載與解壓縮 GCC toolchain source code,可直接改成所需版本號
1
2
$ wget http://gcc.parentingamerica.com/releases/gcc-7.1.0/gcc-7.1.0.tar.bz2
$ tar xf gcc-7.1.0.tar.bz2
  1. 進入 source code 目錄,並下載所需相關檔案
1
2
$ cd gcc-7.1.0
$ contrib/download_prerequisites
  1. 建立建置用目錄,並進入此目錄,配置好 source code 目錄位置與相關設定
1
2
3
4
5
6
7
8
9
$ mkdir build && cd build
$ ../gcc-7.1.0/configure -v --build=x86_64-linux-gnu \
--host=x86_64-linux-gnu \
--target=x86_64-linux-gnu
--prefix=/usr/local/gcc-7.1 \
--enable-checking=release \
--enable-languages=c,c++,fortran \
--disable-multilib \
--program-suffix=-7.1

設定說明
* –build

    指定編譯 GCC toolchain 的平台

*  --host

    指定編譯後的 GCC toolchain 是執行在什麼平台

*  --target

    指定編譯後的 GCC toolchain 是將 source code 編譯到什麼平台

* --prefix

    指定編譯後的 GCC toolchain 的安裝位置

* --program-suffix

    指定編譯後的 GCC toolchain 的執行檔結尾修飾名稱,例如:gcc-7.1,"-7.1" 即為結尾修飾名稱
  1. 執行編譯流程
1
$ make -j 8 
  1. 執行安裝流程
1
$ make install

最後即可在安裝目錄底下使用 GCC toolchain

在撰寫碩士論文中,遇到需要把BibTex轉成bibitem格式的情況,在此紀錄下方法

建立一個dummy.tex的檔案

將以下內容複製貼上

1
2
3
4
5
6
\documentclass{article}
\begin{document}
\nocite{*}
\bibliography{reference}
\bibliographystyle{plain}
\end{document}

接著在Termimal輸入

1
2
3
4
$ latex dummy
$ bibtex dummy
$ bibtex dymmy
$ latex dummy

dummy.bbl裡頭便是\bibtem格式了

  1. 先將Vundle抓下來
1
$ git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
  1. 下面內容複製到~/.vimrc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
set nocompatible
filetype off

" NERDTree Key
map <F1> :NERDTree <CR>
let g:NERDTreeWinPos = 'right'

set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()

" Let Vundle manage itself
Plugin 'VundleVim/Vundle.vim'

" Better file browser
Plugin 'scrooloose/nerdtree'
" Code commenter
Plugin 'scrooloose/nerdcommenter'
" Surround
Plugin 'tpope/vim-surround'
" Autoclose
Plugin 'Townk/vim-autoclose'
" Airline
Plugin 'bling/vim-airline'
" Terminal Vim with 256 colors colorscheme
Plugin 'fisadev/fisa-vim-colorscheme'
" Git integration
Plugin 'motemen/git-vim'

" Plugin 'Valloric/YouCompleteMe'

" " SnipMate
Plugin 'MarcWeber/vim-addon-mw-utils'
Plugin 'tomtom/tlib_vim'
Plugin 'garbas/vim-snipmate'
Plugin 'honza/vim-snippets'

" markdown
Plugin 'plasticboy/vim-markdown'

" "Python and other languages code checker
Plugin 'scrooloose/syntastic'

" Rust
Plugin 'rust-lang/rust.vim'

call vundle#end()

" NERDTree Key
map <F1> :NERDTree <CR>
let g:NERDTreeWinPos = 'right'

" NERDcommenter
let g:NERDSpaceDelims = 1

" Airline
set laststatus=2
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#left_sep = ' '
let g:airline#extensions#tabline#left_alt_sep = '|'
let g:airline#extensions#tabline#right_sep = ' '
let g:airline#extensions#tabline#buffer_nr_show = 1
let g:airline_powerline_fonts = 1
" let g:airline_theme = 'luna'
let g:airline#extensions#whitespace#enabled = 0

if !exists('g:airline_symbols')
let g:airline_symbols = {}
endif
let g:airline_left_sep = ''
let g:airline_left_alt_sep = ''
let g:airline_right_sep = ''
let g:airline_right_alt_sep = '|'
let g:airline_symbols.branch = ''
let g:airline_symbols.readonly = '|'
let g:airline_symbols.linenr = '|'

let g:ycm_global_ycm_extra_conf = '~/.ycm_extra_conf.py'
let g:ycm_confirm_extra_conf = 0
let g:ycm_key_list_select_completion=[]
let g:ycm_key_list_previous_completion=[]

" Disable markdown folding
let g:vim_markdown_folding_disabled = 1

" allow plugins by file type (required for plugins!)
filetype plugin on
filetype indent on

autocmd BufRead,BufNewFile *.ll set filetype=llvm

set expandtab
set tabstop=4
set softtabstop=4
set shiftwidth=4

set incsearch
set hlsearch

set backspace=2
set autoindent
set ruler
set showmode
set nu
set bg=dark
syntax on

set clipboard=unnamed

colorscheme default
  1. 安裝Plugin

    開啟vim

1
$ vim
執行安裝動作
1
:PluginInstall
0%