最早,现有ed,ed为ex之父,ex为vi之父,而vi为vim之父 —- The Old Testament of Unix

这些早期的Unix编辑器,依旧可以在vim中找到它们的影子,他们没有消失,只是换了一个方式存在。

我打算挖一坑,来說一下命令行模式,来看一下vim身体里流淌着多少它的祖先ex(行编辑器)的血液。

在普通模式下,按下:就会进入命令行模式,和shell下的命令行很相似;输入一条命令,然后回车执行。按下Esc键就可以回到普通模式。这些在命令行模式下执行的命令,又可以称为Ex命令。

常见命令 用途说明
:edit 编辑一个文件,editk可以简写为e
:write 写文件
:tabnew 创建一个tab
:prev/:next 当用vim一次打开多个文件(如:vim a.txt b.txt)后,可以用他们来回切换文件
:bprev/:bnext 当打开多个缓冲区后,可以用他们来回切换缓冲区,不过我习惯ctrl+6来回切换最近两个缓冲区
:[range]delete [x] 删除指定范围的行到寄存器[x]中,delete可以简写为d
:[range]yank [x] 复制指定范围的行到寄存器[x]中,yank可以简写为y
:[line]put [x] 把寄存器x的内容,粘贴到指定行的后面,put不能简写
:[range]copy {address} 把指定范围的行复制到{address}指定的行之下,copy可以简写为co或t
:[range]move {address} 把指定范围的行移动到{address}指定的行之下,move可简写为m
:[range]join 把指定范围内的行连接起来,成为一行,J也可以起连接行的作用(当前行和下一行)
:[range]normal {commands} 对指定范围内的每一行执行普通模式的命令{commands}
:[range]substitute/{pattern}/{string}/{flags} 把指定范围内的行出现的{pattern}匹配的地方替换为{string},substitute 可以简写为s(vim的正则替换,我先挖个坑,后面再填上)
:[range]global/{pattern}/[cmd] 把指定范围内的行匹配{pattern}的所有行之下Ex命令{cmd},这个特性还要进一步挖掘

range的写法: - 一个数字如23,34;代表指定的行 - 两个数字逗号分割: 2,5 代表从第2到第5行 - num,. 从第num行到当前行,比如我们要从第7行删除所有内容,我们先按G,光标会移动到最后一行,然后输入 :7,. d

总之,Ex命令可以一次执行,多处修改。

时序图(Sequence Diagram),又名序列图、循序图,是一种UML交互图。它通过描述对象之间发送消息的时间顺序显示多个对象之间的动态协作。它可以表示用例的行为顺序,当执行一个用例行为时,其中的每条消息对应一个类操作或状态机中引起转换的触发事件。

一个小demo

	sequenceDiagram
		Alice ->> John: Hi John,nice day, Uh huh?
		John  -->> Alice: Yeap
sequenceDiagram Alice ->> John: Hi John,nice day, Uh huh? John -->> Alice: Yeap

基本概念

  • participant(参与者,先定义的会先现实出来)
  • alice(别名,参与者可以起别名,定义别名后,就只能用别名了,如果混用,会是两个参与者)
  • message(消息,[participant][arrow][participant]:Message text)
  • activation(激活,可对参与者进行激活和去激活,可以重复进行)
    • activate/deactivate [participant] 激活或取消
    • -->+ 加号激活
    • -->- 减号取消,通过+/-明显比较方便(但是,有时候会失效)
  • note(便签, Note [right of | left of | over] [participant])
    • Note right of John: Foo12345
    • Note left of Alice: An note
    • Note over Alice,John: Cross the world
  • loop(循环)
  • alt(分支,选择,相当于 if else )
  • opt(可选,相当于 if)
    sequenceDiagram
      participant John
      participant A as  Alice
      A ->> John : Hi,John
      Note left of John: Foo12345
      John  -->> A: Alice..I
      Note right of A : An note
      activate A
      A ->>+ John :  1
      John -->> A : 2
      deactivate A
      A -x- John : 3
      John --x A :4 
      loop Every 30 seconds
          John -->> A : heart bits
          A -->> John : ACK
      end
      A ->> John : Are you ok?
      alt is ok
          John -->>A: Ok啊
      else so so 
          John -->>A: 还活着
      else
          John -->>A: 还不错
      end
      Note over A, John: Over!
    
sequenceDiagram participant John participant A as Alice A ->> John : Hi,John Note left of John: Foo12345 John -->> A: Alice..I Note right of A : An note activate A A ->>+ John : 1 John -->> A : 2 deactivate A A -x- John : 3 John --x A :4 loop Every 30 seconds John -->> A : 还在么?(heart bits) alt is ok A ->> John : 在呢,我还在,莫担心 else 没反应 John -->> John : Alice is lose,释放他的资源 end end A ->> John : Are you ok? alt is ok John -->>A: Ok啊 else so so John -->>A: 还活着 else John -->>A: 还不错 end opt 心情好 A -->> Tom : 出来撸串 end Note over A, John: Over!
箭头类型 描述
-> 实线无箭头
--> 点线无箭头
->> 实线有箭头
-->> 点线有箭头
-x 实线带叉和箭头
--x 点线带叉和箭头

微信JSAPI支付流程

  • 文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_4
  • 官方流程图:
微信JSAPI支付流程
  • 用mermaid模仿上图
	sequenceDiagram
		participant User
		participant WechatApp
		participant MB as MerchantBackend
		participant WPS as WechatPaySystem
		
		MB ->> MB:1.生成图文信息链接或二维码
		MB -->>+ User :展示给用户
		User->>+ WechatApp:2.点击链接或扫描二维码在微信浏览器打开商户H5网页
		WechatApp ->>+ MB:网页内请求生成订单
		MB ->>+ MB:4.生成商户订单
		deactivate MB
		MB ->>+ WPS:5.调用统一下单API
		WPS ->>+ WPS:生成预付单
		deactivate WPS
		WPS -->> MB:返回预付单信息(prepay_id)
		deactivate WPS
		WPS -->> MB:返回预付单信息(prepay_id)
		MB ->>+ MB:6.生成JSAPI页面调用的支付参数并签名	
		deactivate MB
		MB -->> WechatApp:返回支付参数(prepay_id.paySign等)
		deactivate WechatApp
		User ->>+ WechatApp:7.用户点击发起支付
		WechatApp ->>+ WPS: JSAPI接口请求支付
		WPS ->>+ WPS:8.检查参数合法性和授权权限
		deactivate MB
		WPS -->> WechatApp: 返回验证结果,并要求支付授权
		deactivate WPS
		WechatApp ->>+ WechatApp:提示输入密码
		deactivate WechatApp
		deactivate WechatApp
		User ->>+ WechatApp:9.确认支付,输入密码
		WechatApp ->>+ WPS:提交授权
		WPS ->>+ WPS:验证授权
		deactivate WPS
		alt 并行处理
			WPS ->>+ MB:10.异步通知支付结果			
		else
			MB -->> WPS:11.告知微信通知处理结果
			deactivate MB
		else
			WPS -->> WechatApp:12.返回支付结果,并发微信消息提示
			deactivate WPS
		end
		WechatApp -->> User:展示支付信息给用户
		deactivate User
		deactivate WechatApp
		
		WechatApp ->>+ WechatApp: 微信跳转回商户H5页面
		activate WechatApp
		WechatApp ->>+ MB:13.查询商户后台支付结果
		alt 支付结果
			else 未收到支付通知
			MB ->>+ WPS:14.调用查询API,查询支付结果
			WPS -->> MB:返回支付结果
			deactivate WPS
		end
		MB -->> WechatApp:返回支付结果
		WechatApp ->>+ WechatApp:15.商户发货及支付后个性化页面提示
		deactivate WechatApp
		deactivate WechatApp
		deactivate WechatApp

sequenceDiagram participant User participant WechatApp participant MB as MerchantBackend participant WPS as WechatPaySystem MB ->> MB:1.生成图文信息链接或二维码 MB -->>+ User :展示给用户 User->>+ WechatApp:2.点击链接或扫描二维码在微信浏览器打开商户H5网页 WechatApp ->+ MB:网页内请求生成订单 MB ->>+ MB:4.生成商户订单 deactivate MB MB ->>+ WPS:5.调用统一下单API WPS ->>+ WPS:生成预付单 deactivate WPS WPS -->> MB:返回预付单信息(prepay_id) deactivate WPS WPS -->> MB:返回预付单信息(prepay_id) MB ->>+ MB:6.生成JSAPI页面调用的支付参数并签名 deactivate MB MB -->> WechatApp:返回支付参数(prepay_id.paySign等) deactivate WechatApp User ->>+ WechatApp:7.用户点击发起支付 WechatApp ->>+ WPS: JSAPI接口请求支付 WPS ->>+ WPS:8.检查参数合法性和授权权限 deactivate MB WPS -->> WechatApp: 返回验证结果,并要求支付授权 deactivate WPS WechatApp ->>+ WechatApp:提示输入密码 deactivate WechatApp deactivate WechatApp User ->>+ WechatApp:9.确认支付,输入密码 WechatApp ->>+ WPS:提交授权 WPS ->>+ WPS:验证授权 deactivate WPS alt 并行处理 WPS ->>+ MB:10.异步通知支付结果 else MB -->> WPS:11.告知微信通知处理结果 deactivate MB else WPS -->> WechatApp:12.返回支付结果,并发微信消息提示 deactivate WPS end WechatApp -->> User:展示支付信息给用户 deactivate User deactivate WechatApp WechatApp ->>+ WechatApp: 微信跳转回商户H5页面 activate WechatApp WechatApp ->>+ MB:13.查询商户后台支付结果 alt 支付结果 else 未收到支付通知 MB ->>+ WPS:14.调用查询API,查询支付结果 WPS -->> MB:返回支付结果 deactivate WPS end MB -->> WechatApp:返回支付结果 WechatApp ->>+ WechatApp:15.商户发货及支付后个性化页面提示 deactivate WechatApp deactivate WechatApp deactivate WechatApp

回头可以画很多协议的原理图,比如http,tcp等等,先挖一个坑,后续再填上。 点击查看原文,图的预览效果应该更好一些。

昨日,国内的公司发了三个社交app,多闪、马桶MT、聊天宝。我觉得互联网应该是要去中心化的, 特别是社交类的app,颠覆者,应该是去中心化的产品。

some picture of mermaid

graph LR id1(Start)-->id2(Stop) style id1 fill:#f9f,stroke:#333,stroke-width:4px,width:70px,height:50px style id2 fill:#ccf,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5 linkStyle 0 stroke:#ff3,stroke-width:4px;
graph TB c1-->a2 subgraph one a1-->a2 end subgraph two b1-->b2 end subgraph three c1-->c2 end
graph LR A1 --> B1 A2 --- B2 C --text in the link --- B3 D ---|text_on_link| B4 E -->|text| B5 F -.-> B6 F -.->|text in line| Te H -.->|text| Note N1 ==>|text| N3 Node["dd#quot\;"] Node1["#quot;A dec char:#9829;"] Node === Node1
graph TB c1-->a2 subgraph one a1-->a2 end subgraph two b1-->b2 end subgraph three c1-->c2 end
graph LR id1(Start)-->id2(Stop) style id1 fill:#f9f,stroke:#333,stroke-width:4px,width:70px,height:50px style id2 fill:#ccf,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5 linkStyle 0 stroke:#ff3,stroke-width:4px;
use jekyll to generate github pages

graph LR id1(Start)-->id2(Stop) style id1 fill:#f9f,stroke:#333,stroke-width:4px,width:70px,height:50px style id2 fill:#ccf,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5 linkStyle 0 stroke:#ff3,stroke-width:4px;
graph TB c1-->a2 subgraph one a1-->a2 end subgraph two b1-->b2 end subgraph three c1-->c2 end
graph LR A1 --> B1 A2 --- B2 C --text in the link --- B3 D ---|text_on_link| B4 E -->|text| B5 F -.-> B6 F -.->|text in line| Te H -.->|text| Note N1 ==>|text| N3 Node["dd#quot\;"] Node1["#quot;A dec char:#9829;"] Node === Node1
graph TB c1-->a2 subgraph one a1-->a2 end subgraph two b1-->b2 end subgraph three c1-->c2 end
graph LR id1(Start)-->id2(Stop) style id1 fill:#f9f,stroke:#333,stroke-width:4px,width:70px,height:50px style id2 fill:#ccf,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5 linkStyle 0 stroke:#ff3,stroke-width:4px;
Previm -- a vim plugin preview the markdown file

vim下有很多支持markdown文件预览的插件。今天找到了一个很简单而且功能相对强大的vim插件previm。 是一个日本开发者的开源项目(https://github.com/previm/previm/blob/master/README-en.mkd) 需要依赖的library和插件很少。准确说预览reStructuredText文档需要rst2html的一个python工具外。

安装previme

  • 先安装依赖

      pip install docutils  ## python2.7
      rst2html --version    ## reStructuredText文档需要这个rst2html工具
    
  • 修改~/.vimrc文件(我用的是vundle管理vim插件), 关于vim插件管理,我先在这里挖个坑,以后再填上

      call vundle#begin()
    
      ......
    
      Plugin 'previm/previm'  " 添加到vundle的调用之间
    
      ......
    
      call vundle#end()
    		
      ......
    			
      let g:previm_open_cmd = 'google-chrome -a' " 用chrome预览
      " let g:previm_open_cmd = 'firefox -a'  " 用firefox预览
      " 为了避免.md被理解为modula2文件,添加以下说明
      augroup PrevimSettings
          autocmd!
          autocmd BufNewFile,BufRead *.{md,mdwn,mkd,mkdn,mark*} set filetype=markdown
      augroup END
    
  • 一点小改动

      文档上的previm_open_cmd不合适,需要改成如上
      :h g:previm_open_cmd 
      # open by FireFox
      let g:previm_open_cmd = 'open -a Firefox'
      # open with Google Chrome
      let g:previm_open_cmd = 'open -a Google\ Chrome'
    

使用

  • 编辑一个md文档,需要预览文件时,输入:PrevimOpen 打开浏览器预览
  • 修改文件后,预览文件会动态更新

  • 对mermaid的支持
    sequenceDiagram
      participant Alice
      participant Bob
      Alice->>John: Hello John, how are you?
      loop Healthcheck
          John->>John: Fight against hypochondria
      end
      Note right of John: Rational thoughts<br/>prevail...
      John-->>Alice: Great!
      John->>Bob: How about you?
      Bob-->>John: Jolly good!
    
  • reStructuredText,编辑后,:PreviewOpen

预览效果图

预览效果