multiconfig —— Golang 简易项目配置方案

目录: go | 标签: | 发布时间:

我们平时在做任何项目时都少不了配置,Golang 项目也不例外。 在 Golang 的标准库中,并没有整套的配置方案,只有 flag 包来解析命令行参数和 os 包来获取当前环境变量等。 现在,我们来看一看一个 Golang 的第三方简易项目配置库,那就是 multiconfig

理想的项目配置方案

一个好的项目配置方案应该能用多种方式来配置选项,并且具有固定的优先顺序。

个人认为理想的顺序应该如下:

  1. 程序内应该为每个配置选项设定一个默认值,确保程序正确运行。
  2. 配置文件,例如toml、json、xml等,可以覆盖程序内配置,常用于不同开发、测试或正式环境的配置。
  3. 环境变量,可以覆盖前两种配置,可用于不同机器或运行环境。
  4. 运行命令时的参数,拥有最高优先级,能覆盖所有的配置,能完全个性化任何项目。

下面我们通过示例,实际体验 multiconfig 如何实现和操作这种优先顺序的。

阅读更多>>


Go Modules —— 官方包管理工具

目录: go | 标签: | 发布时间:

一直以来,golang 官方都没有附带包管理工具,默认是通过 GOPATH 来管理第三方模块的,后来增加了 vendor 功能来隔离项目。 后面又出现了一些第三方的包管理工具,例如:godep、glide、govendor 等,都能很大程度上解决包管理的问题。

Go Modules 是什么

从2018年3月开始,官方就计划开始填坑了,见 https://github.com/golang/go/issues/24301。 在6,7月发布的beta版本中就已经正式装载了 Modules 功能,直到8月正式发布1.11版本,算是正式登上了历史舞台。

由于我8月正好新开始一个go项目,在调研包版本工具时发现了这个计划,并稍作尝试后,就决定使用这个了。 当然,刚开始的时候还是使用的beta版本,后面正式版本出来后,才切换为了正式版本。

按照官方的说法,Modules 能把关联的包都聚集在一起管理,能精确记录依赖要求,创建可重复的构建。

下面,我们来简要看看如何使用。

阅读更多>>


[译] Vimscript 有路勤为径 —— 接下来呢?

目录: vim | 标签: | 发布时间:

接下来呢?

如果你已经读到这了,并且完成了所有的例子和练习,那肯定已经非常牢固地掌握了基本的 Vimscript。 不过不用着急,还有大量的的内容可以学习!

如果还渴望更多内容,这里还有几个有意思的话题供你学习。

配色方案

在本书中,我们为 Potion 文件添加过了语法高亮。 而另一方面,是创造自定义配色方案,它定义了每个语法元素应该显示什么颜色。

Vim 的配色方案制作起来非常得简单直接,但有点重复。 阅读 :help highlight 来学习基本要素。 你可能想看看一些内置的配色方案是如何组织文件的。

如果你准备好接受挑战,那可以看下我的 Bad Wolf 配色方案的源码, 看看我是如何利用 Vimscript 使得定义和维护更轻松的。 留意“palette”中的字典和 HL 函数,它会动态构建 highlight 命令。

command 命令

很多插件允许用户通过按键映射和方法调用来进行交互,但有些则更喜欢创建额外命令作为替代。 例如,Fugitive 插件创建了像 :Gbrowse:Gdiff 这样的命令,并交给用户来决定如何调用。

这样的命令通过 :command 命令创建。阅读 :help user-commands 来学习如何创建属于自己的命令。 你现在应该已经非常熟悉 Vimscript 了,要学习新命令,阅读 Vim 的文档应该就够了。

阅读更多>>


[译] Vimscript 有路勤为径 —— 分发

目录: vim | 标签: | 发布时间:

分发

目前为止,你已经拥有了足够的技术来创建一个有用的 Vim 插件了。 本章节会教你把插件放在网上并使它们易于使用,以及如何对潜在用户进行宣传。

托管

你需要做的第一件事就是把你的插件放到网上,这样其他人才能下载它。 目前 Vim 插件的权威地址是 Vim 网站中的脚本板块

你需要有一个网站中的免费账号。一旦有了,就可以点击“添加脚本”的链接,然后填好表单。 这些应该是一目了然的。

但在最近几年中,一个新的趋势就是把插件仓库托管到一个公开的地方,例如 Bitbucket 或 GitHub。 这种方式的普及可能要归结于两个因素。 首先,Pathogen 的出现使得在各自目录中维护已安装的插件代码变得轻松。 另外,像 Mercurial 和 Git 这样的分布式版本控制系统和像 Bitbucket 和 GitHub 这样的公开托管网站的崛起也起了很大的影响。

对于把自己的配置文件放在版本控制中的人来说把代码仓库提供出来是很方便的。 Mercurial 用户可以用 Mercurial 的“子仓库”功能来保持关注插件的版本, 而 Git 用户可以用子模块功能(但只能用于其他的 Git 仓库,而不像 Mercurial 的子仓库功能)。

保留每个已安装插件的完整仓库也能让你在它们出问题的时候方便调试。 你可以用文件标注(blame),二分查找(bisection),以及任何版本控制系统提供的工具来找出哪里出问题了。 而且如果把仓库留在了电脑中,也能便于你回馈修复漏洞的代码。

希望我已经说服你也应该使自己的插件仓库公开可用。 使用了哪种服务并不重要,只要仓库在某处可用就行了。

阅读更多>>


[译] Vimscript 有路勤为径 —— 文档

目录: vim | 标签: | 发布时间:

文档

我们的 Potion 插件中有很多有用的功能,但并不是对任何人都真的有用, 我们需要编写良好的文档,这样他们才能知道它能做什么!

Vim 本身的文档是非常棒的。它没有过度冗长,但确十分缜密。 这也鼓励很多插件作者认真地编写文档,并使 Vimscript 社区形成了一种编写强健文档的良好习惯。

文档如何工作

当阅读一个 Vim 的 :help 主题时,你肯定会注意到有些内容会高亮显示,明显不同于其他的。 让我们看看这是如何工作的。

打开任意一个帮助主题(例如 :help help)并运行 :set filetype?。Vim 会显示 filetype=help。 现在运行 :set filetype=text,会看到高亮消失了。再次 :set filetype=help,又会变回来。

这说明 Vim 帮助文件只是和其他类型的文件一样会把文本语法高亮! 这意味着你可以自己写代码来达到同样的效果。

在插件仓库中创建一个名为 doc/potion.txt 的文件。 当 Vim/Pathogen 构建帮助主题时,会在 doc 目录中寻找这些文件, 所以我们会在这个文件中为我们的插件编写帮助文档。

在 Vim 中打开这个文件,并运行 :set filetype=help,这样就能在输入的时候就看到语法高亮了。

阅读更多>>


[译] Vimscript 有路勤为径 —— 自动加载

目录: vim | 标签: | 发布时间:

自动加载

我们已经为 Potion 插件写了相当多的功能了,而这些是在本书中要完成的全部内容。 在结束之前,我们还会再讲一些重要的东西来完善它,给它增加亮点。

位居首位的是通过自动加载来让我们的插件更效率。

自动加载如何工作

目前,当一个用户载入我们的插件(通过打开一个 Potion 文件),所有的功能都会被加载。 我们的插件还很小,所以这不是个大问题,但是对于更大的插件来说,加载所有的代码会花费相当多的时间。

Vim 的解决方法是一种名为“自动加载”的功能。自动加载可以延迟加载代码,直到它真正需要的时候才会加载。 全部而言,并不会有太大的优化,但如果用户并不总是用到所有的代码,那自动加载就能提升很大的速度。

下面是它如何工作的。看看以下命令:

:call somefile#Hello()

当你运行这个命令时,Vim 表现的会和调用普通的函数会有些区别。

如果这个函数已经被加载过了,Vim 只会像往常一样调用它。

否则,Vim 会在 ~/.vim 目录(以及所有的 Pathogen bundles)中寻找一个叫 autoload/somefile.vim 的文件。

如果这个文件存在,Vim 会载入并执行它。然后再尝试调用这个函数。

在这个文件中,函数应该像这样定义:

function somefile#Hello()
    " ...
endfunction

你可以在函数名上使用多个 # 字符来表示子目录。例如:

:call myplugin#somefile#Hello()

这会寻找 autoload/myplugin/somefile.vim 文件。 它里面的函数需要用完整的自动载入路径来定义:

function myplugin#somefile#Hello()
    " ...
endfunction

阅读更多>>


[译] Vimscript 有路勤为径 —— 外部命令

目录: vim | 标签: | 发布时间:

外部命令

Vim 遵从 UNIX “做好一件事”的理念。 把所有能想到的功能都塞进编辑器中并不是一个好的办法,而是应该在适当的时候代理给外部命令。

让我们在插件中添加一些和 Potion 编译器的交互,并开始接触 Vim 的外部命令。

编译

首先,我们会添加一个命令来编译并运行当前的 Potion 文件。 有很多方式来做到这个,但目前我们只会简单地使用一个外部命令。

在插件仓库中创建一个 potion/ftplugin/potion/running.vim 文件。 我们会在这里面创建映射,用来编译并运行 Potion 文件。

if !exists("g:potion_command")
    let g:potion_command = "potion"
endif

function! PotionCompileAndRunFile()
    silent !clear
    execute "!" . g:potion_command . " " . bufname("%")
endfunction

nnoremap <buffer> <localleader>r :call PotionCompileAndRunFile()<cr>

第一段代码检查一个储存执行 Potion 命令的全局变量是否设置过,如果没有,则把它储存起来。 我们之前就看过这种检查方式了。

如果 potion 不在 $PATH 中,这会允许用户在 ~/.vimrc 文件中通过添加一行类似 let g:potion_command = "/Users/sjl/src/potion/potion" 的代码来重写它。

最后一行添加了一个缓冲本地的映射,它调用上面定义的函数。 记住,因为这个文件是在 ftdetect/potion 目录中的, 在每次文件的 filetype 被设为 potion 时,都会被运行。

真正的功能在 PotionCompileAndRunFile() 函数中。 继续,保存文件,打开 factorial.pn 然后按下 <localleader>r 来运行映射,看看会发生什么。

如果 potion 在你的 $PATH 中,文件就会被运行,并且会在终端中 (或者,如果你用的是图形界面的 Vim,会在窗口的底部)看到它的输出。 如果看到一个错误说找不到 potion 命令,你就需要在 ~/.vimrc 文件中设置 g:potion_command, 就像上面提到的那样。

让我们看一看 PotionCompileAndRunFile() 函数时如何工作的。

阅读更多>>


[译] Vimscript 有路勤为径 —— Potion 段落移动

目录: vim | 标签: | 发布时间:

Potion 段落移动

既然已经了解了段落移动是如何工作的, 那就让我们在 Potion 文件中把这些命令以某种方式添加到映射中来。

首先,我们需要决定什么是 Potion 文件中的一个“段落”。 现在有两对段落移动命令,所以我们可以提供两种“方案”,而用户可以随意使用一种自己喜欢的。

我们用以下两种方案来定义 Potion 段落开始的位置:

  1. 任何在空行下面、并且首字符不是空白符的行,或者文件的第一行。
  2. 任何首字符不是空白符、包含一个等号、并且以冒号结尾的行。

以下是稍微扩充后的 factorial.pn 文件,并且展示了这些规则会把哪些行作为段落头部:

# factorial.pn                              1
# Print some factorials, just for fun.

factorial = (n):                            1 2
    total = 1

    n to 1 (i):
        total *= i.

    total.

print_line = ():                            1 2
    "-=-=-=-=-=-=-=-\n" print.

print_factorial = (i):                      1 2
    i string print
    '! is: ' print
    factorial (i) string print
    "\n" print.

"Here are some factorials:\n\n" print       1

print_line ()                               1
10 times (i):
    print_factorial (i).
print_line ()

第一种定义更宽松。它把段落大致定义为一段“最高层级的文本块”。

第二种定义更严格。它把段落定义为(实际上就是)函数的定义。

阅读更多>>


[译] Vimscript 有路勤为径 —— 段落移动原理

目录: vim | 标签: | 发布时间:

段落移动原理

如果你从来没用 Vim 的段落移动命令([[]][],以及][),那现在就花点时间来阅读它们的帮助文档。 同时也阅读下 :help section

是不是晕了?没关系,我第一次阅读这些内容也是一样。 我们将通过写代码的方式快速学习这些移动是如何工作的,然后在下一章节,我们会创建自己的 Potion 插件来支持它们。

nroff 文件

这4种“段落移动”命令从概念上来说表示在文件的“段落”之间移动。

这些命令都是被设计出来在nroff 文件中默认就能用的。 nroff 是一种类似 Latex 或者 Markdown 的语言 —— 它用来编写文本,然后进行格式化 (实际上就是 UNIX 帮助文档用到的格式)。

nroff 文件用一系列的“宏”来定义“段落头部”。例如,下面是引用的一段 awk 帮助文档:

.SH NAME                                                     ***
awk \- pattern-directed scanning and processing language
.SH SYNOPSIS                                                 ***
.B awk
[
.BI \-F
.I fs
]
[
.BI \-v
.I var=value
]
[
.I 'prog'
|
.BI \-f
.I progfile
]
[
.I file ...
]
.SH DESCRIPTION                                              ***
.I Awk
scans each input
.I file
for lines that match ...

.SH 开始的行就是段落头部。我用 *** 标记了它们。 这4个段落移动命令会使你的光标在这些段落头部行之间移动。

Vim 把任何以 . 和一个 nroff 头部宏开始的行都当作是段落头部行,即使你并不是在编辑 nroff 文件

你可以通过修改 sections 选项来修改宏,但是 Vim 仍会要求在行开始位置有个区间段, 并且宏必须是配对的字符,所以,这个选项并没有给 Potion 文件带来足够的灵活性。

阅读更多>>


[译] Vimscript 有路勤为径 —— 高级折叠

目录: vim | 标签: | 发布时间:

高级折叠

在上一章节中,我们使用了 Vim 的 indent 折叠来给 Potion 文件添加一些快速但有污染的折叠。

打开 factorial.pn 文件,按下 zM 以确保所有的折叠都关闭了。现在文件应该看上去如下:

factorial = (n):
+--  5 lines: total = 1

10 times (i):
+--  4 lines: i string print

切换第一个折叠,然后会如下:

factorial = (n):
    total = 1
    n to 1 (i):
+---  2 lines: # Multiply the running total.
    total.

10 times (i):
+--  4 lines: i string print

这看上去很棒,但是我个人更喜欢把代码块的第一行和它的内容一起折叠。 在本章节中,我们会编写一些自定义的折叠代码,当我们完成后,这些折叠将会看上去像这样:

factorial = (n):
    total = 1
+---  3 lines: n to 1 (i):
    total.

+--  5 lines: 10 times (i):

这样更紧凑并且易于阅读(对于我来说)。如果你更喜欢 indent 的方式也是可以的, 但是无论如何也请完成本章,这样可以获得一些编写 Vim 折叠表达式的实践经验。

阅读更多>>

加载更多