基本上vi可以分为四种状态,分别是命令模式(command mode)、插入模式(Insert mode)、底行模式(last line mode)和虚拟模式(Virtual mode),各模式的功能区分如下:
控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到 last line mode。
只有在Insert mode下,才可以做文字输入,按「ESC」键可回到命令行模式。
将文件保存或退出vi,也可以设置编辑环境,如寻找字符串、列出行号……等。
可视化模式提供一种灵活易用的方法选择一块文本供操作符使用。它也是选择一个文本块的唯一方法。
不过一般我们在使用时把vi简化成两个模式,就是将底行模式也算命令行模式。
所以我们只需要知道三种模式就可以了,而这三种模式切换常用的如下图:
vi /etc/services
| 快捷键 | 用途 | 快捷键 | 用途 |
|---|---|---|---|
| a | 从光标所在位置后面开始新增 | A | 从光标所在行行尾新增 |
| i | 从光标所在位置前面插入 | I | 从光标所在行的第一个非空格字符前面插入 |
| o | 在光标所在行下新增一行并进入输入模式 | O | 在光标所在行上新增一行并进入输入模式 |
| s | 删除当前字符插入 | S | 删除当前行插入 |
| gg | 到文本头部 | G | 到文本尾部 |
| c0 | 剪切至行头 |
| c$ | 剪切至行尾 |
| ncw | 向前剪切n个词 |
| ncb | 向后剪切n个词 |
| ncc | 向下剪切n行 |
| y0 | 复制至行头 |
| y$ | 复制至行尾 |
| nyw | 向前复制n个词 |
| nyb | 向后复制n个词 |
| nyy | 向下复制n行 |
| nx | 删除n个字符 |
| d0 | 删除至行头 |
| d$ | 删除至行尾 |
| ndw | 向前删除n个词 |
| ndb | 向后删除n个词 |
| ndd | 向下删除n行 |
| np | 粘贴n次 |
| p(小写) | 粘贴光标右边 |
| P(大写) | 粘贴光标左边 |
/^http.*80[^0-9]\+
| :%s#http#abc#g | 全部替换 |
| :20,30s/http/abc | 范围替换 |
| ← | h |
| up | k |
| → | l |
| down | j |
| 0 | 行头 |
| ^ | 行头 |
| $ | 行尾 |
| w | 一个词向前 |
| b | 一个词向后 |
| shift+r | 进入 |
| 快捷键 | 用途 | 快捷键 | 用途 |
|---|---|---|---|
| :wq | 保存退出 | :q! | 不保存退出 |
| :w | 保存不退出 | :x | 保存退出 |
| ZZ | 保存退出 | ZQ | 不保存退出 |
| 快捷键 | 用途 | 快捷键 | 用途 |
|---|---|---|---|
| x | 删除光标所在位置的字符 | dd | 删除光标所在的行 |
| r | 修改光标所在位置的字符,接着输入新的字符 | R | 进入替换状态,新增字符会覆盖原有字符,直到按 [ESC] 回到指令模式下为止 |
| s | 删除光标所位置字符,并进入输入模式 | S | 删除光标所在行,并进入输入模式 |
| 0 | 移动到光标所在行的行首 | $ | 移动到光标所在行的行尾 |
| CTRL-n | 移动到下一行 | CTRL-p | 移动到上一行 |
| CTRL-d | 向下半页 | CTRL-f | 向下一页 |
| CTRL-u | 向上半页 | CTRL-b | 向上一页 |
| H | 移动到窗口的首行 | M | 移动到窗口的中间行 |
| L | 移动到窗口的末行 | J | 连接相邻的两行 |
| d0 | 移动到光标所在行行首 | ( | 移动到光标所在行的上一行 |
| ) | 移动到光标所在行的下一行 | { | 移动光标所在段落的结尾 |
| } | 移动光标所在段落的开头 | n- | 向上移动n行 |
| n+ | 向下移动n行 | nG | 移动到第n行 |
| b | 移动到光标处的单词第一个字母处 | w | 移动到后一个单词的第一个字母 |
| e | 移动到光标处的单词最后一个字母处 |
:e test.rst
:split [file] :new [file]
CTRL-W 轮循各窗口
:vsplit [file] :vnew [file]
CTRL-W h move to the window on the left CTRL-W j move to the window below CTRL-W k move to the window above CTRL-W l move to the window on the right CTRL-W t move to the TOP window CTRL-W b move to the BOTTOM window
注意: 如果你不熟悉vi的键盘移动方法,可以使用CTRL-W + 上下左右箭头
:wall :wqall (:wqall!) :qall (:qall!) :only (CLOSING ALL OTHER WINDOWS) :close
常用的用:
:set nu(number) 设置行号 :set syntax=on(off) 设置颜色(也可用这种方式:syntax clear,:syntax enable) :set ts=4 (tabstop) 设置tab=4 :set wrap=on 是否换行 :set co=125 设置显示列 :set ft? 显示文件类型
:mdebug1
:`debug1
q进入录制模式,后面的a表示将录制过程的宏名,dd是删除一行字符的命令,q表示录制结束
举例说明
qaddq
2@a表示执行刚刚录制的过程a两次。
qs0fId$jq 先到行首0定位到I开头的字母fI,删除至行尾d$,再下移一行j
VG选中然后normal @s就可以调用这个宏了
在命令行模式下
:map <F7> @s<ENTER>
这样就可以直接使用F7调用定义的宏命令了
map nmap vnormap nnoremap inoremap 区别
注意: 按照vim文档的说法,本文方法对vim 6.0以前的版本无效。
编辑~/.vimrc,(最好在其末尾)加入:
set fileencoding=utf-8 set fileencodings=ucs-bom,gb18030,utf-8,default
上面的方法不会对已有文件的编码产生影响。
vim有自动判断编码的功能,这里主要简单介绍几个变量
屏幕显示的编码,如使用utf-8做locale的系统,encoding就应是utf-8以方便显示
供vi尝试的编码列表,vi会逐个尝试每一项,如果没有发生错误,就设置当前的fileencoding为与该项相同的值。如果均失败,fileencoding将为空。
正在被编辑的文件的编码,它也决定新文件的编码。如果为空,表示与encoding相同。如果与encoding不同,vi将会在保存和读取时做二者之间的转换。
set nocp
set ru
"ls.log" [Modified] line 1 of 26 --3%-- col 1
set nu(mber)
set hls set nohls
set ic
set is (incsearch)
set ai
set sw=2 (shiftwidth)
set ts=4
syntax on / syntax off
set sm
set enc=utf8
如果当你设定为 UTF8 的时候却发现 vim 的讯息变成乱码,是因为你本来安装的时候可能是中文的原因,你可以改成英文讯息:
language english
set nobackup
set aw (autowrite)
set gfn=Courier_New:h14
abbr hw homework
这也就是说以后你只要打 hw 之后再打一个空白的话, hw 就会被自动取代成 homework。
不过由于 abbr 设定是对于命令列模式和编辑模式(插入状态)都会成立的,所以:
如果你只想它在编辑模式(插入状态)生效的话,就得用:
iabbr hw homework
但是如果你只想针对命令列输入指令才要作简写取代的话,那就是:
cabbr hw homework
如果要取消这些简写的话,可以在命令列模式下以
:una hw
取消对 abbr hw 的自动取代。同理,cabbr 和 iabbr 就是用 :cuna 和 :iuna 来取消。
:! ls -l
vi +85 /etc/services
在用vi阅读和编写程序时(如C/C++),需要了解某个函数的具体功能和用法,将光标移到函数下面,输入:K就可以查看man手册
:X 接着输入密码,确认密码,然后 “:wq”保存退出。文件已经被加密
:X 接着输入空密码,然后保存退出
:3,$s/^/Hello/g
:%s/old_string/new_string/g
:3,7s/old_string/new_string/
Vim7.1使用鼠标时会默认进入虚拟选中模式(visual mode),就好像通过v选中的一样。通过下面的方式:
启用虚拟选中:
set mouse-=a
禁用虚拟选中:
set mouse=
添加下行至配置文件 ~/.vimrc
set mouse-=a
有三种方式可以进入“可视选择”模式
v 光标以字符的形式选择内容。 shift+v 光标以行的形式选中内容。 Ctrl+V 光标以块的形式选中内容,可以是横向,也可以是纵向。
选中内容都可以操作,如复制(y),剪切©,粘贴(p)
:set list
刚刚提到 vim 的设定档,在 windows 上的话是 vimrc,如果是 UNIX 系统的话就是 .vimrc。在 windows 上的系统的话,看你把 vim 安装在什麽地方,那麽在你安装目录下就会发现 _vimrc (同时可能也会有gvimrc),比方我安装在 C:\vim ,那在 C:\vim\ 下就会看到 _vimrc。那在 UN*IX 下的话,你可以在自己的 home 目录下编写自己的 .vimrc
set fileencodings=utf-8 set termencoding=utf-8 set encoding=utf-8 set tabstop=4 set softtabstop=2 set expandtab set autoindent
一般来说在 vim 裡面,如果你指的是环境设定的话,通常会用 set optionname 来表示; 如果不要的話就是用 set nooptionname。
#cat ~/.vimrc set nocompatible set number filetype on set history=1000 set background=dark syntax on set autoindent set smartindent set tabstop=4 set shiftwidth=4 set showmatch set guioptions-=T set vb t_vb= set ruler set nohls set incsearch if has("vms") set nobackup else set backup endif set fileencodings=utf-8,gbk
LDFLAGS="-rdynamic" ./configure --prefix=/opt/vim91 --with-features=huge --enable-multibyte \ --enable-python3interp --with-python3-config-dir=$(python3-config --configdir) \ --enable-luainterp --enable-cscope --enable-gui make -j4 install
pip3 install python-lsp-server
git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
:BundleList -> 列举列表(也就是.vimrc)中配置的所有插件 :BundleInstall -> 安装列表中的全部插件 :BundleInstall! -> 更新列表中的全部插件 :BundleSearch foo -> 查找foo插件 :BundleSearch! foo -> 刷新foo插件缓存 :BundleClean -> 清除列表中没有的插件 :BundleClean! -> 清除列表中没有的插件
" vundle if filereadable(expand("~/.vimrc.bundles")) source ~/.vimrc.bundles endif if filereadable(expand("~/.vimrc.gui")) source ~/.vimrc.gui endif if filereadable(expand("~/.vimrc.html")) source ~/.vimrc.html endif " 修改leader键 let mapleader = ',' let g:mapleader = ',' " 在上下移动光标时,光标的上方或下方至少会保留显示的行数 set scrolloff=7 " 代码折叠自定义快捷键 <leader>zz let g:FoldMethod = 0 map <leader>zz :call ToggleFold()<cr> function! ToggleFold() if g:FoldMethod == 0 exe "normal! zM" let g:FoldMethod = 1 else exe "normal! zR" let g:FoldMethod = 0 endif endfunction " 相对行号: 行号变成相对,可以用 nj/nk 进行跳转 set relativenumber number au FocusLost * :set norelativenumber number au FocusGained * :set relativenumber " 插入模式下用绝对行号, 普通模式下用相对 autocmd InsertEnter * :set norelativenumber number autocmd InsertLeave * :set relativenumber function! NumberToggle() if(&relativenumber == 1) set norelativenumber number else set relativenumber endif endfunc nnoremap <C-n> :call NumberToggle()<cr> set clipboard=unnamed "map <C-c> y:e ~/clipsongzboard<CR>P:w !pbcopy<CR><CR>:bdelete!<CR> vnoremap <C-c> y:e ~/clipsongzboard<CR>P:w !pbcopy<CR><CR>:bdelete!<CR>:bufdo e<CR> vnoremap <C-y> :w !pbcopy<CR><CR> noremap <C-p> :r !pbpaste<CR><CR> nnoremap :set invpaste paste? imap :set invpaste paste? set pastetoggle= autocmd VimEnter * NERDTree autocmd VimEnter * wincmd p autocmd VimEnter * wincmd l " mapping keys 绑定快捷键 nnoremap t :TlistToggle<CR> nnoremap <F5> :GundoToggle<CR> nnoremap <C-d> a<C-R>=strftime("%c")<CR><Esc> " Smart way to move between windows nnoremap <C-j> <C-W>j nnoremap <C-k> <C-W>k nnoremap <C-h> <C-W>h nnoremap <C-l> <C-W>l " syntax syntax on " nobackup set nobackup set nowb set noswapfile set listchars=tab:>~,trail:. set list au FileType python,php,c,java,javascript,html,htm,smarty call SetOption() function! SetOption() set expandtab " 使用空格代替tab set shiftwidth=2 " 设定 << 和 >> 命令移动时的宽度为 2 set tabstop=2 " 用2个空格代替1个tab set sts=2 " 设置softtabstop 为 2,输入tab后就跳了2格. set cindent " C语言方式缩进 set smartindent " 智能缩进 set autoindent " 自动缩进 set smarttab " 只在行首用tab,其他地方的tab都用空格代替 set showmatch " 在输入括号时光标会短暂地跳到与之相匹配的括号处 " set fdm=inden " 代码折叠 set wrap " 自动换行 set lbr set tw=500 let g:pydiction_location = '/Users/shaohy/.vim/bundle/pydiction/complete-dict' let g:pydiction_menu_height = 5 map <F2> :!python % map <F3> :!python3 % endfunction function! s:ZoomToggle() abort if exists('t:zoomed') && t:zoomed execute t:zoom_winrestcmd let t:zoomed = 0 else let t:zoom_winrestcmd = winrestcmd() resize vertical resize let t:zoomed = 1 endif endfunction command! ZoomToggle call s:ZoomToggle() nnoremap <silent> <Leader>z :ZoomToggle<CR> "设置菜单语言 set langmenu=zh_cn " ========= " 功能函数 " ========= " 获取当前目录 func GetPWD() return substitute(getcwd(), "", "", "g") endf " ========= " 环境配置 " ========= " 保留历史记录 set history=400 " 命令行于状态行 set ch=1 set stl=\ [File]\ %F%m%r%h%y[%{&fileformat},%{&fileencoding}]\ %w\ \ [PWD]\ %r%{GetPWD()}%h\ %=\ [Line]\ %l,%c\ %=\ %P set ls=2 " 始终显示状态行 " 状态栏显示目前所执行的指令 set showcmd " 行控制 set linebreak set nocompatible set textwidth=120 " 行号和标尺 set number set ruler set rulerformat=%15(%c%V\ %p%%%) " 控制台响铃 :set noerrorbells :set novisualbell :set t_vb= "close visual bell " 插入模式下使用 <BS>、<Del> <C-W> <C-U> set backspace=indent,eol,start " 允许backspace和光标键跨越行边界 "set whichwrap+=<,>,h,l " 标签页 set tabpagemax=20 set showtabline=2 " 自动重新读入 set autoread " 自动切换到文件当前目录 set autochdir "在查找时忽略大小写 set ignorecase set incsearch set hlsearch set noai nosi set cursorline "在所有模式下都允许使用鼠标,还可以是n,v,i,c等 set mouse=a " 恢复上次文件打开位置 set viminfo='10,\"100,:20,%,n~/.viminfo " fold set foldmethod=indent set foldlevel=99 " disable auto comment autocmd FileType * set formatoptions-=cro " 返回当前时间 func! GetTimeInfo() "return strftime('%Y-%m-%d %A %H:%M:%S') return strftime('%Y-%m-%d %H:%M:%S') endfunction " 插入模式按 Ctrl + D(ate) 插入当前时间 imap <C-d> <C-r>=GetTimeInfo()<cr> " encoding set fencs=utf-8,usc-bom,shift-jis,gb18030,gbk,gb2312,cp936 set termencoding=utf-8 set encoding=utf-8 set fileencodings=ucs-bom,utf-8,cp936 set fileencoding=utf-8 " ========= " 快捷键 " ========= let NERDTreeWinSize=22 map zz :NERDTreeToggle<cr> " 标签相关的快捷键 Ctrl map tn :tabnext<cr> map tp :tabprevious<cr> map tc :tabclose<cr> map <C-t> :tabnew<cr> map <C-k> :tabclose<cr> map <C-Tab> :tabnext<cr> " 在文件名上按gf时,在新的tab中打开 map gf :tabnew <cfile><cr> " 新建 XHTML 、PHP、Javascript 文件的快捷键 nmap <C-c><C-h> :NewQuickTemplateTab xhtml<cr> nmap <C-c><C-p> :NewQuickTemplateTab php<cr> nmap <C-c><C-j> :NewQuickTemplateTab javascript<cr> nmap <C-c><C-c> :NewQuickTemplateTab css<cr> function! s:CloseIfOnlyNerdTreeLeft() if exists("t:NERDTreeBufName") if bufwinnr(t:NERDTreeBufName) != -1 if winnr("$") == 1 q endif endif endif endfunction autocmd bufnewfile *.py call HeaderPython() " add generic header to python files function HeaderPython() let l = 0 let l = l + 1 | call setline(l,'#!/usr/bin/env python') let l = l + 1 | call setline(l,'# coding=utf-8') endfunction autocmd bufnewfile *.sh call HeaderShell() " add generic header to bash files function HeaderShell() let l = 0 let l = l + 1 | call setline(l,'#!/bin/sh') let l = l + 1 | call setline(l,'# -*- coding: utf-8 -*-') endfunction
cat > ~/.config/pycodestyle <<EOF [pycodestyle] count = False ignore = E111, E114 max-line-length = 160 statistics = True EOF
if &compatible set nocompatible end set rtp+=~/.vim/bundle/Vundle.vim/ " ========= " 插件 " ========= filetype on filetype plugin on " 启用插件,必须required! filetype plugin indent on " plugin list 插件列表 call vundle#begin() " Let Vundle manage Vundle Plugin 'prabirshrestha/async.vim' Plugin 'prabirshrestha/asyncomplete.vim' Plugin 'prabirshrestha/vim-lsp' Plugin 'prabirshrestha/asyncomplete-lsp.vim' Plugin 'gmarik/Vundle.vim' Plugin 'scrooloose/nerdtree' Plugin 'vim-scripts/taglist.vim' Plugin 'nicoraffo/conque' Plugin 'Yggdroot/indentLine' Plugin 'sjl/gundo.vim' Plugin 'rizzatti/dash.vim' Plugin 'auto-pairs' Plugin 'pydiction' Plugin 'jelera/vim-javascript-syntax' Plugin 'othree/html5.vim' Plugin 'plasticboy/vim-markdown' Plugin 'Xuyuanp/nerdtree-git-plugin' Plugin 'kien/ctrlp.vim' " Plugin 'Valloric/YouCompleteMe' " 这个插件需另外安装和配置!!! call vundle#end() " =============== " 开启lsp server " =============== if executable('pyls') au User lsp_setup call lsp#register_server({ \ 'name': 'pyls', \ 'cmd': {server_info->['pyls']}, \ 'whitelist': ['python'], \ }) endif nnoremap <C-m>s :call SystemdMenu()<CR> function SystemdMenu() let l = line(".") - 1 let l = l + 1 | call append(l,"# https://zh.opensuse.org/openSUSE:How_to_write_a_systemd_service") let l = l + 1 | call append(l,"[Unit]") let l = l + 1 | call append(l,"Description=Daemon to start He.net IPv6") let l = l + 1 | call append(l,"# Before After") let l = l + 1 | call append(l,"After=network.target syslog.target") let l = l + 1 | call append(l,"# Requires Wants Conflicts OnFailure PartOf BindsTo") let l = l + 1 | call append(l,"Wants=network.target network-online.target") let l = l + 1 | call append(l,"") let l = l + 1 | call append(l,"# Automount Mount Device Path Scope Service Slice Snapshot Socket Swap Target Timer") let l = l + 1 | call append(l,"[Service]") let l = l + 1 | call append(l,"# simple forking oneshot dbus") let l = l + 1 | call append(l,"Type=oneshot") let l = l + 1 | call append(l,"RemainAfterExit=yes") let l = l + 1 | call append(l,"TimeoutStartSec=0") let l = l + 1 | call append(l,"TimeoutStopSec=0") let l = l + 1 | call append(l,"LimitNOFILE=1048576") let l = l + 1 | call append(l,"LimitNPROC=1048576") let l = l + 1 | call append(l,"Environment=TMPDIR=/var/tmp") let l = l + 1 | call append(l,"EnvironmentFile=/etc/sysconfig/network/config") let l = l + 1 | call append(l,"Nice=0") let l = l + 1 | call append(l,"ExecStartPre=/usr/bin/test 'x${NETWORKMANAGER}' = xyes") let l = l + 1 | call append(l,"ExecStart=") let l = l + 1 | call append(l,"ExecStartPost=") let l = l + 1 | call append(l,"ExecStop=") let l = l + 1 | call append(l,"ExecStopPost=") let l = l + 1 | call append(l,"# no always on-failure on-abnormal on-abort on-success") let l = l + 1 | call append(l,"Restart=no") let l = l + 1 | call append(l,"RestartSec=") let l = l + 1 | call append(l,"ExecReload=") let l = l + 1 | call append(l,"") let l = l + 1 | call append(l,"[Install]") let l = l + 1 | call append(l,"WantedBy=multi-user.target") let l = l + 1 | call append(l,"Also=") let l = l + 1 | call append(l,"Alias=") endfunction
LDFLAGS="-rdynamic" ./configure --prefix=/opt/vim91 --with-features=huge --enable-multibyte \ --enable-python3interp --with-python3-config-dir=$(python3-config --configdir) \ --enable-luainterp --enable-cscope --enable-gui
git submodule update --init --recursive python3.10 install.py --clang-completer --force-sudo --verbose
所以VS Code 就提出了 “Language Server” (简称 LSP)这种先进的概念。这是一种 Client-Server 架构,每个语言实现自己的 Language Server,每个编辑器去实现自己对接 Language Server 的前端。这样一个语言只需要实现一次,就可以支持所有的编辑器。上面那种情况,只要有3个语言的补全实现+3个编辑器自己的 Language Server 实现就可以了。
所以我索性放弃YCM了,转向了vim-lsp。
vim-lsp 是一个与 LSP 交互的插件,类似于一个 Vim 的 SDK。
pip install python-language-server Plugin 'prabirshrestha/async.vim' Plugin 'prabirshrestha/asyncomplete.vim' Plugin 'prabirshrestha/vim-lsp' Plugin 'prabirshrestha/asyncomplete-lsp.vim' if executable('pyls') au User lsp_setup call lsp#register_server({ \ 'name': 'pyls', \ 'cmd': {server_info->['pyls']}, \ 'whitelist': ['python'], \ }) endif
" ========= " 图形界面 " ========= if has('gui_running') set anti " Mac OS X 用平滑反锯齿的字体 " 只显示菜单 set guioptions=mcr " 高亮光标所在的行 set cursorline " 编辑器配色 "colorscheme zenburn "colorscheme dusk if has("win32") " Windows 兼容配置 source $VIMRUNTIME/mswin.vim " f11 最大化 nmap <f11> :call libcallnr('fullscreen.dll', 'ToggleFullScreen', 0)<cr> nmap <Leader>ff :call libcallnr('fullscreen.dll', 'ToggleFullScreen', 0)<cr> " 自动最大化窗口 au GUIEnter * simalt ~x " 给 Win32 下的 gVim 窗口设置透明度 au GUIEnter * call libcallnr("vimtweak.dll", "SetAlpha", 250) " 字体配置 exec 'set guifont='.iconv('Courier_New', &enc, 'gbk').':h11:cANSI' exec 'set guifontwide='.iconv('微软雅黑', &enc, 'gbk').':h11' endif if has("unix") && !has('gui_macvim') set guifont=Courier\ 10\ Pitch\ 11 set guifontwide=YaHei\ Consolas\ Hybrid\ 11 endif if has("gui_macvim") " MacVim 下的字体配置 set guifont=Menlo:h12 set guifontwide=Hei:h12 " 半透明和窗口大小 set transparency=2 set lines=40 columns=110 " 使用MacVim原生的全屏幕功能 let s:lines=&lines let s:columns=&columns func! FullScreenEnter() set lines=999 columns=999 set fu endf func! FullScreenLeave() let &lines=s:lines let &columns=s:columns set nofu endf func! FullScreenToggle() if &fullscreen call FullScreenLeave() else call FullScreenEnter() endif endf " Mac 下,按 \\ 切换全屏 nmap <Leader><Leader> :call FullScreenToggle()<cr> " Set input method off set imdisable " Set QuickTemplatePath let guickTemplatePath = $HOME.'/.vim/templates/' " 如果为空文件,则自动设置当前目录为桌面 lcd ~/Desktop/ " 自动切换到文件当前目录 set autochdir " Set QuickTemplatePath let guickTemplatePath = $HOME.'/.vim/templates/' endif endif " ========= " AutoCmd " ========= if has("autocmd") filetype plugin indent on " 括号自动补全 func! AutoClose() :inoremap ( ()<ESC>i :inoremap " ""<ESC>i :inoremap ' ''<ESC>i :inoremap { {}<ESC>i :inoremap [ []<ESC>i :inoremap } <c-r>=ClosePair('}')<CR> :inoremap ] <c-r>=ClosePair(']')<CR> :inoremap ) <c-r>=ClosePair(')')<CR> endf func! ClosePair(char) if getline('.')[col('.') - 1] == a:char return "\<Right>" else return a:char endif endf "auto close quotation marks for PHP, Javascript, etc, file au FileType php,c,python,javascript exe AutoClose() " Auto Check Syntax "au BufWritePost,FileWritePost *.js,*.php call CheckSyntax(1) " JavaScript 语法高亮 au FileType html,javascript let g:javascript_enable_domhtmlcss = 1 " 给 Javascript 文件添加 Dict if has('gui_macvim') || has('unix') au FileType javascript setlocal dict+=~/.vim/dict/javascript.dict else au FileType javascript setlocal dict+=$VIM/vimfiles/dict/javascript.dict endif " 格式化 JavaScript 文件 "au FileType javascript map <f12> :call g:Jsbeautify()<cr> au FileType javascript set omnifunc=javascriptcomplete#CompleteJS " 给 CSS 文件添加 Dict if has('gui_macvim') || has('unix') au FileType css setlocal dict+=~/.vim/dict/css.dict else au FileType css setlocal dict+=$VIM/vimfiles/dict/css.dict endif " 增加 ActionScript 语法支持 au BufNewFile,BufRead *.as setf actionscript " CSS3 语法支持 au BufRead,BufNewFile *.css set ft=css syntax=css3 " 增加 Objective-C 语法支持 au BufNewFile,BufRead,BufEnter,WinEnter,FileType *.m,*.h setf objc " 将指定文件的换行符转换成 UNIX 格式 au FileType php,javascript,html,css,python,vim,vimwiki set ff=unix " 保存编辑状态 au BufWinLeave * if expand('%') != '' && &buftype == '' | mkview | endif au BufRead * if expand('%') != '' && &buftype == '' | silent loadview | syntax on | endif " 自动最大化窗口 if has('gui_running') if has("win32") au GUIEnter * simalt ~x "elseif has("unix") "au GUIEnter * winpos 0 0 "set lines=999 columns=999 endif endif endif "acp 自动补全插件 let g:AutoComplPop_Behavior = { \ 'c': [ {'command' : "\<C-x>\<C-o>", \ 'pattern' : ".", \ 'repeat' : 0} \ ] \}
autocmd bufnewfile *.htm* call HtmlHeader() nnoremap <C-m>h :call HtmlHeader()<CR> function HtmlHeader() let l = line(".") - 1 let l = l + 1 | call append(l,"<!DOCTYPE html>") let l = l + 1 | call append(l,"<html>") let l = l + 1 | call append(l,"<head>") let l = l + 1 | call append(l,"<title>HTML|Bootstrap</title>") let l = l + 1 | call append(l,"<meta charset='utf-8' name='viewport' content='width=device-width,initial-scale=1.0'>") let l = l + 1 | call append(l,"<link rel=\"stylesheet\" href=\"http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css\">") let l = l + 1 | call append(l,"</head>") let l = l + 1 | call append(l,"<body>") let l = l + 1 | call append(l,"<script src=\"http://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js\"></script>") let l = l + 1 | call append(l,"<script src=\"http://cdn.static.runoob.com/libs/bootstrap/3.3.7/js/bootstrap.min.js\"></script>") let l = l + 1 | call append(l,"</body>") let l = l + 1 | call append(l,"</html>") endfunction nnoremap <C-m>d :call HtmlDiv()<CR> function HtmlDiv() let l = line(".") - 1 let l = l + 1 | call append(l, "<div class='fluid-container'><div class='row'>") let l = l + 1 | call append(l,"<div class='col-xs-12' style='background-color: #dedef8;'>span 12</div>") let l = l + 1 | call append(l,"</div></div>") endfunction nnoremap <C-m>t :call HtmlTable()<CR> function HtmlTable() let l = line(".") - 1 let l = l + 1 | call append(l, "<div class='table-responsive'><table class='table table-hover table-condensed table-striped'>") let l = l + 1 | call append(l,"<caption>Table Example</caption>") let l = l + 1 | call append(l,"<thead><tr><th>Name</th><th>Sex</th></tr></thead>") let l = l + 1 | call append(l,"<tbody>") let l = l + 1 | call append(l,"<tr class='active'><td>Shaohy</td><td>Male</td></tr>") let l = l + 1 | call append(l,"<tr class='success'><td>Amy</td><td>Female</td></tr>") let l = l + 1 | call append(l,"<tr class='waring'><td>May</td><td>Female</td></tr>") let l = l + 1 | call append(l,"<tr class='danger'><td>Jerry</td><td>Male</td></tr>") let l = l + 1 | call append(l,"</tbody></table></div>") endfunction nnoremap <C-m>m :call HtmlMenu()<CR> function HtmlMenu() let l = line(".") - 1 let l = l + 1 | call append(l,"<div class='dropdown'>") let l = l + 1 | call append(l,"<button type='button' class='btn dropdown-toggle' id='dropdownMenu1' data-toggle='dropdown'>喜爱的语言 <span class='glyphicon glyphicon-cloud glyphicon-pencil glyphicon-search glyphicon-heart'></span></button>") let l = l + 1 | call append(l,"<ul class='dropdown-menu' role='menu' aria-labelledby='dropdownMenu1'>") let l = l + 1 | call append(l,"<li role='presentation' class='dropdown-header'>系统编程</li>") let l = l + 1 | call append(l,"<li role='presentation'><a role='menuitem' tabindex='-1' href='#'>Java</a></li>") let l = l + 1 | call append(l,"<li role='presentation' class='divider'></li>") let l = l + 1 | call append(l,"<li role='presentation' class='dropdown-header'>脚本编程</li>") let l = l + 1 | call append(l,"<li role='presentation'><a role='menuitem' tabindex='-1' href='#'>Python</a></li>") let l = l + 1 | call append(l,"</ul></div>") endfunction nnoremap <C-m>a :call HeaderAuthor()<CR> " add generic header to markdown files function HeaderAuthor() "normal gg "normal O let l = -1 let l = l + 1 | call append(l, "#Title: " . expand("%:t:r")) let l = l + 1 | call append(l, "#Date: ". strftime("%Y-%m-%d %H:%M")) let l = l + 1 | call append(l, "#Author: Shaohy<shaohaiyang@gmail.com>") let l = l + 1 | call append(l, "#Tags: ") let l = l + 1 | call append(l, "#Slug: " . expand("%:t:r")) endfunction
nnoremap <C-m>T :call Turtle()<CR> function Turtle() let l = line(".") - 1 let l = l + 1 | call append(l,"import turtle as tt ") let l = l + 1 | call append(l,"import random") let l = l + 1 | call append(l,"w,h = 450,600") let l = l + 1 | call append(l,"life =5") let l = l + 1 | call append(l,"speed = 20") let l = l + 1 | call append(l,"nums = 8") let l = l + 1 | call append(l,"ufos = []") let l = l + 1 | call append(l,"") let l = l + 1 | call append(l,"win = tt.Screen()") let l = l + 1 | call append(l,"win.title('Turtle Game')") let l = l + 1 | call append(l,"win.bgcolor('white')") let l = l + 1 | call append(l,"win.setup(w, h)") let l = l + 1 | call append(l," ") let l = l + 1 | call append(l,"win.tracer(0) # 禁用刷新") let l = l + 1 | call append(l,"pen = tt.Pen() # 定义记分笔") let l = l + 1 | call append(l,"pen.ht()") let l = l + 1 | call append(l,"pen.speed(0)") let l = l + 1 | call append(l,"pen.up()") let l = l + 1 | call append(l,"pen.goto(-35,h/2 - 25)") let l = l + 1 | call append(l,"pen.write(\"生命力: %s\" % life,False,align=\"left\",font=(\"Arial\",18,\"normal\"))") let l = l + 1 | call append(l,"") let l = l + 1 | call append(l,"player = tt.Pen(shape='triangle') # 定义玩家") let l = l + 1 | call append(l,"player.shapesize(2,2)") let l = l + 1 | call append(l,"player.speed(0)") let l = l + 1 | call append(l,"player.fillcolor('red')") let l = l + 1 | call append(l,"player.up()") let l = l + 1 | call append(l,"player.goto(0,-h/2 + 30)") let l = l + 1 | call append(l,"player.seth(90)") let l = l + 1 | call append(l," ") let l = l + 1 | call append(l,"def newtt(): # 创建一只乌龟") let l = l + 1 | call append(l," color = (random.random(), random.random(),random.random())") let l = l + 1 | call append(l," ufo = tt.Pen(shape='turtle')") let l = l + 1 | call append(l," ufo.speed(0)") let l = l + 1 | call append(l," ufo.shapesize(1,1)") let l = l + 1 | call append(l," ufo.pencolor(color)") let l = l + 1 | call append(l," ufo.fillcolor(color)") let l = l + 1 | call append(l," ufo.up()") let l = l + 1 | call append(l," ufo.seth(270)") let l = l + 1 | call append(l," ufo.goto(random.randint(-w/2,w/2), h/2 - 10)") let l = l + 1 | call append(l," ufos.append(ufo)") let l = l + 1 | call append(l," ") let l = l + 1 | call append(l,"for _ in range(nums):") let l = l + 1 | call append(l," newtt()") let l = l + 1 | call append(l," ") let l = l + 1 | call append(l,"win.tracer(1) # 刷新屏幕") let l = l + 1 | call append(l,"") let l = l + 1 | call append(l,"def turnleft(): # 左移") let l = l + 1 | call append(l," global pos,speed") let l = l + 1 | call append(l," player.goto(pos - speed, -h/2 + 30)") let l = l + 1 | call append(l,"def turnright(): # 右移") let l = l + 1 | call append(l," global pos,speed") let l = l + 1 | call append(l," player.goto(pos + speed, -h/2 + 30)") let l = l + 1 | call append(l,"def fast(): # 加速") let l = l + 1 | call append(l," global speed") let l = l + 1 | call append(l," speed += 5") let l = l + 1 | call append(l,"def slow(): # 减速") let l = l + 1 | call append(l," global speed") let l = l + 1 | call append(l," speed -= 5") let l = l + 1 | call append(l," ") let l = l + 1 | call append(l,"tt.listen()") let l = l + 1 | call append(l,"tt.onkey(turnleft,\"Left\")") let l = l + 1 | call append(l,"tt.onkey(turnright,\"Right\")") let l = l + 1 | call append(l,"tt.onkey(fast,\"Up\")") let l = l + 1 | call append(l,"tt.onkey(slow,\"Down\")") let l = l + 1 | call append(l,"") let l = l + 1 | call append(l,"#win.tracer(1,25)") let l = l + 1 | call append(l,"while 1:") let l = l + 1 | call append(l," for i in ufos:") let l = l + 1 | call append(l," # 踫撞 或者 出界 ") let l = l + 1 | call append(l," if player.distance(i) < 20 or i.ycor() < -h/2 :") let l = l + 1 | call append(l," if player.distance(i) < 20:") let l = l + 1 | call append(l," life += 1 ") let l = l + 1 | call append(l," pen.clear()") let l = l + 1 | call append(l," pen.write(\"生命力: %s\" % life,False,align=\"left\",font=(\"Arial\",18,\"normal\"))") let l = l + 1 | call append(l," if i.ycor() < -h/2 :") let l = l + 1 | call append(l," life -= 1 ") let l = l + 1 | call append(l," pen.clear()") let l = l + 1 | call append(l," pen.write(\"生命力: %s\" % life,False,align=\"left\",font=(\"Arial\",18,\"normal\"))") let l = l + 1 | call append(l," i.fd(0)") let l = l + 1 | call append(l," color = (random.random(), random.random(),random.random())") let l = l + 1 | call append(l," i.pencolor(color)") let l = l + 1 | call append(l," i.fillcolor(color)") let l = l + 1 | call append(l," i.up()") let l = l + 1 | call append(l," i.goto(random.randint(-w/2,w/2), h/2 - 10)") let l = l + 1 | call append(l," else:") let l = l + 1 | call append(l," i.fd(random.randrange(1,20,2))") let l = l + 1 | call append(l,"") let l = l + 1 | call append(l," pos = player.xcor()") let l = l + 1 | call append(l," if pos >= w/2:") let l = l + 1 | call append(l," pos = w/2 - 25") let l = l + 1 | call append(l," if pos <= -w/2:") let l = l + 1 | call append(l," pos = -w/2 + 25") let l = l + 1 | call append(l,"") let l = l + 1 | call append(l,"tt.done()") endfunction
nnoremap <C-m>g :call Pygame()<CR> function Pygame() let l = line(".") - 1 let l = l + 1 | call append(l,"import pygame,sys,random") let l = l + 1 | call append(l,"from pygame.locals import *") let l = l + 1 | call append(l,"") let l = l + 1 | call append(l,"pygame.init()") let l = l + 1 | call append(l,"size = x, y = 1000,800") let l = l + 1 | call append(l,"title = 'PyGame Demo'") let l = l + 1 | call append(l,"running = True") let l = l + 1 | call append(l,"") let l = l + 1 | call append(l,"pygame.display.set_caption(title)") let l = l + 1 | call append(l,"pygame.mouse.set_visible(False) # 隐藏鼠标") let l = l + 1 | call append(l,"pygame.key.set_repeat(200) # 设置长按键盘不放,延时200ms触发事件") let l = l + 1 | call append(l,"screen = pygame.display.set_mode(size) # 设置画布") let l = l + 1 | call append(l,"") let l = l + 1 | call append(l,"class Ball(pygame.sprite.Sprite):") let l = l + 1 | call append(l," def __init__(self,d=50,color=(255,255,255),pos=(0,0),speed = 0): # 设置 直径,颜色,位置,速度") let l = l + 1 | call append(l," super().__init__()") let l = l + 1 | call append(l," self.image = pygame.Surface((d,d),SRCALPHA) # 创建一个透明的表面") let l = l + 1 | call append(l," pygame.draw.circle(self.image,(color),(d//2,d//2),d//2)") let l = l + 1 | call append(l," self.rect = self.image.get_rect(") let l = l + 1 | call append(l," center = pos") let l = l + 1 | call append(l," )") let l = l + 1 | call append(l," self.x = self.y = speed") let l = l + 1 | call append(l," def update(self): # 设置精灵的运动函数") let l = l + 1 | call append(l," if self.x != 0:") let l = l + 1 | call append(l," if self.rect.left < 0 or self.rect.right > x:") let l = l + 1 | call append(l," self.x = -self.x") let l = l + 1 | call append(l," if self.rect.top < 0 or self.rect.bottom > y:") let l = l + 1 | call append(l," self.y = -self.y") let l = l + 1 | call append(l," self.rect.move_ip(self.x,self.y)") let l = l + 1 | call append(l," ") let l = l + 1 | call append(l,"hole = Ball(150,(0,0,0),(x/2,y/2))") let l = l + 1 | call append(l,"all = pygame.sprite.Group()") let l = l + 1 | call append(l,"all.add(hole)") let l = l + 1 | call append(l,"") let l = l + 1 | call append(l,"while running:") let l = l + 1 | call append(l," screen.fill((255,255,255))") let l = l + 1 | call append(l," for e in pygame.event.get():") let l = l + 1 | call append(l," if e.type == QUIT:") let l = l + 1 | call append(l," running = False") let l = l + 1 | call append(l," if e.type == KEYDOWN:") let l = l + 1 | call append(l," if e.key == K_ESCAPE:") let l = l + 1 | call append(l," running = False") let l = l + 1 | call append(l," if e.key == K_SPACE:") let l = l + 1 | call append(l," color = (") let l = l + 1 | call append(l," random.randint(50,250),") let l = l + 1 | call append(l," random.randint(50,250),") let l = l + 1 | call append(l," random.randint(50,250),") let l = l + 1 | call append(l," )") let l = l + 1 | call append(l," new_ball = Ball(") let l = l + 1 | call append(l," 50,") let l = l + 1 | call append(l," color,") let l = l + 1 | call append(l," (random.randint(50,x-50),random.randint(50,y-50)),") let l = l + 1 | call append(l," random.randint(4,10)") let l = l + 1 | call append(l," )") let l = l + 1 | call append(l," all.add(new_ball)") let l = l + 1 | call append(l," all.draw(screen)") let l = l + 1 | call append(l," all.update()") let l = l + 1 | call append(l," pygame.display.update()") endfunction
neovim 是一个 vim 的分支,vim 是一个文本编辑器,neovim 是 vim 的一个分支,它的目标是提供一个更好的 vim,而不是 vim 的替代品。
neovim 和 vim 有什么区别呢? 区别在于 neovim 重构了 vim 的代码,在兼容 vimscipt 的基础上,支持了 lua 脚本作为配置语言。同时 neovim 在 Github 上比 vim 的社区更加活跃。neovim 有更用的 lsp 服务器,可以理解 neovim 是 vim 的超集。
yum remove -y git-* yum install -y https://packages.endpointdev.com/rhel/7/os/x86_64/endpoint-repo.x86_64.rpm yum install -y git git clone https://github.com/LazyVim/starter ~/.config/nvim
之后,可以通东风破 来安装 rime 的wubi和pinyin-simp 两个输入方案。
sudo dnf install -y librime ibus-rime librime-tools
然后通过编辑~/.config/ibus/rime/default.custom.yaml文件来配置wubipinyin混合输入方案 <code bash> patch: schemalist:
menu:
page_size: 9 style: horizontal: true ascii_composer/switch_key: Shift_L: commit_code Shift_R: commit_code
</code>
ibus restart
在 fedora 终端下面显示的中文十分难看,常常还会出现黑体、宋体夹着出现的情形。研究了一会儿后发现与系统的等宽(monospace)字体配置有关。
sudo yum install -y wqy-microhei-fonts wqy-bitmap-fonts wqy-unibit-fonts wqy-zenhei-fonts
如果想使用文泉驿正黑等宽作为最优默认等宽,可修改
/etc/fonts/conf.d/65-nonlatin.conf
找到 <family>monospace</family> 后,在 <prefer> 下面添上一行:
<family>WenQuanYi Micro Hei Mono</family>
这样终端的中文字体终于显示正常,而且浏览器显示代码快内的中文时也一样没有问题,真是舒服多了。
比如说实现widnows下的经典 super + d 一键显示桌面
桌面空白处右键选择【设置】-> 【键盘】-> 【键盘快捷键】-> 【导航】->【隐藏所有正常窗口】