Python 多版本使用 pip

Q:Fedora 31 提供的 Python3.7, 想使用 Python3.8, 用系统的pip3 只会给 Python3.7 安装库,如何解决

A:

1
2
curl -O https://bootstrap.pypa.io/get-pip.py
python3.8 get-pip.py

执行上面命令后,会在 /usr/local/bin/ 下生成和 pip 相关的脚本,把这些脚本删除,要不可能会和系统的 pip3 冲突。
接下来就可以使用下面的命令行安装 Python3.8 的库

python3.8 -m pip install pyhash --user

在安装过程中可能会因为众所周知的原因导致网络出错,备好梯子即可。

gogs 皮肤和源码升级

gogs 使用了也有一年多了,小团队使用基本还行。有几个问题,第一界面代码 merge 有问题,第二不支持代码 review,
如果能解决上面两个问题就好用很多了。下面两段是年前折腾 gogs 的记录,没有啥技术含量,只是做个备份。

切换皮肤

https://github.com/Kos-M/GogsThemes 提供了两款皮肤,文中给出的方法要修改 gogs 配置,直接使用 TamperMonkey 就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// ==UserScript==
// @name Gogs Theme
// @resource IMPORTED_CSS https://raw.githubusercontent.com/Kos-M/GogsThemes/master/themes/dark_theme.css
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match http://website:8000/*
// @grant GM_getResourceText
// @grant GM_addStyle
// ==/UserScript==

(function() {
'use strict';
const my_css = GM_getResourceText("IMPORTED_CSS");
GM_addStyle(my_css);
})();

使用后效果图

源码升级

gogs 已经有一年多没有提供二进制的安装包了,看了改进不少,就尝试了源码升级。
参考 https://gogs.io/docs/installation/install_from_source#%E6%B5%8B%E8%AF%95%E5%AE%89%E8%A3%85

安装 golang

参考 Google 官方文档,执行下面命令就可以了。 https://go.dev/doc/install

1
2
3
wget https://go.dev/dl/go1.17.6.linux-amd64.tar.gz
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.17.6.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin

编译

1
2
3
4
5
6
# 克隆仓库到 "gogs" 子目录
git clone --depth 1 https://github.com/gogs/gogs.git gogs
# 修改工作目录
cd gogs
# 编译主程序,这个步骤会下载所有依赖
go build -o gogs

编译过程会下载文件(需要自备梯子),编译完成后将在 gogs 工作目下生成 gogs 可执行文件

打包

gogs 源码的 Makefile 提供了打包命令,执行 make pack 即可,将在 release 目生成 gogs.20220112095054.zip

迁移配置

将 gogs.20220112095054.zip 解压,这就类似 gogs 的二进制升级了 https://gogs.io/docs/upgrade/upgrade_from_binary

1
2
3
4
mv gogs gogs_old
cp -R gogs_old/custom gogs
cp -R gogs_old/data gogs
cp -R gogs_old/log gogs

gogs 0.13 的配置已经发生了变化,如果不修改配置执行 ./gogs web会出现错误

1
2
3
2022/01/12 09:40:06 [ INFO] Gogs 0.13.0+dev
2022/01/12 09:40:06 [FATAL] [...github/internal/route/install.go:75 GlobalInit()] Failed to initialize ORM engine:
open database: failed to connect to `host=127.0.0.1 user=root database=gogs`: dial error (dial tcp 127.0.0.1:3306: connect: connection refused)

看错误像是在连接 mysql 的 3306 端口,可是配置文件设置的是使用 sqlite,非常困惑。上网搜索后证实是 gogs 0.13 的配置文件的字段修改了。

最关键的两个字段是数据库相关的 DB_TYPE 改为 TYPEPASSWD 改为 PASSWORD 修改后 custom/conf/app.ini 后,执行 ./gogs web 一切正常。

github clone 加速

国内因为众所周知的原因,git clone 一直很慢,最近可能状况就更糟糕了。@TeleMan 提供了一个信息,可以
通过修改 host 文件达到加速效果。经过测试,只要修改两条记录即可

1
2
199.232.69.194                github.global.ssl.fastly.net
140.82.113.4 github.com

修改后,速度快多了,直连

1
2
3
4
5
6
7
8
git clone https://github.com/googleprojectzero/winafl.git
正克隆到 'winafl'...
remote: Enumerating objects: 1538, done.
remote: Counting objects: 100% (175/175), done.
remote: Compressing objects: 100% (108/108), done.
remote: Total 1538 (delta 90), reused 130 (delta 60), pack-reused 1363
接收对象中: 100% (1538/1538), 5.29 MiB | 765.00 KiB/s, 完成.
处理 delta 中: 100% (846/846), 完成.

使用一段时间后发现不是太稳定,终极大法还是需要一个长长的梯子,此方法记为备用方案。

在 vim 中使用 LeaderF 和 gtags

☆ 缘由和一些 vim 历史

前些年 vim 没有子窗口的概念,日本的一个 vim 插件作者为了解决这个问题生撸了一套流程,当时 unite.vim 横空出世惊艳了我一把。后面随着技术发展,neovim 和 vim 先后引入了 floating window ,这才使得情况变得好了一点。

https://github.com/vim/vim/blob/master/runtime/doc/popup.txt
https://neovim.io/doc/user/api.html#api-floatwin

得益于新技术,在 vim 中使用 LeaderF 插件的交互体验上了一个台阶。

Demo

neovim 从 0.9 版本开始放弃对 cscope 的支持 https://twitter.com/Neovim/status/1580933880579641344

这给我阅读源码造成了一些问题,虽然 vim 仍然可以使用 cscope,但 vim 的启动速度不如 nvim 快,所以我开始寻找替代方案。同时,我发现 denite.nvim,unite.vim,作者也不怎么维护了,一想似乎是很多年没有维护 vim 配置了。

在网络上搜索在 neovim 上阅读源码的方法,无意发现有人提到用 LeaderF 替代 tagbar,于是有了现在的这篇文章。

☆ 安装vim 插件 LeaderF

插件的仓库地址:https://github.com/Yggdroot/LeaderF/tree/master

使用 Vundle.vim 安装,在 .vimrc 中添加下面一行

1
Plug 'Yggdroot/LeaderF', { 'do': ':LeaderfInstallCExtension' }

在 vim 中执行下面命令,即可成功安装,如果遇到网络问题,自己挂上线路即可。

1
2
:so %
:PlugInstall

☆ LeaderF 配置

1
2
3
4
5
6
7
8
9
10
11
12
let g:Lf_WorkingDirectoryMode = 'Ac'
let g:Lf_RootMarkers = ['.git', '.svn', '.hg', '.project', '.root']
let g:Lf_DefaultExternalTool='rg'
let g:Lf_WindowPosition = 'popup'

let g:Lf_UseCache = 0
let g:Lf_PreviewInPopup = 1
"let g:Lf_CacheDirectory = s:cachedir
let g:Lf_ShowHidden = 1 "show hidden files

" preview or not
let g:Lf_PreviewResult = {'Function': 0, 'BufTag': 0 }
  • g:Lf_WorkingDirectoryMode = ‘AF’ 设置工作目录,如果没有找到 RootMarker 以当前文件所在目录作为工作目录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
g:Lf_WorkingDirectoryMode                       *g:Lf_WorkingDirectoryMode*
This option customizes LeaderF's working directory.
e.g., >
let g:Lf_WorkingDirectoryMode = 'Ac'
<
c - the directory of the current working directory.(default)
a - the nearest ancestor of current working directory that contains one of
directories or files defined in |g:Lf_RootMarkers|. Fall back to 'c' if
no such ancestor directory found.
A - the nearest ancestor of current file that contains one of directories
or files defined in |g:Lf_RootMarkers|. Fall back to 'c' if no such
ancestor directory found.
f - the directory of the current file.
F - if the current working directory is not the direct ancestor of current
file, use the directory of the current file as LeaderF's working
directory, otherwise, same as 'c'.
Note: if "f", "F" is included with "a" or "A", use the behavior of "f" or
"F"(as a fallback) when a root can't be found.

  • g:Lf_DefaultExternalTool 索引文件使用的外部工具,可选值为 ‘rg’, ‘pt’, ‘ag’, ‘find’,作者推荐使用 rg
  • g:Lf_UseCache 列文件时是否使用缓存,默认值为 1,设置为 0 不使用缓存
  • g:Lf_WindowPosition,LeaderF 窗口的位置,可选值有 top, bottom, left, right, popup,fullscreen,默认值为 bottom
  • g:Lf_PreviewInPopup 设置是否在 LeaderF 的 popup 窗口显示预览, 默认值为 0
  • g:Lf_ShowHidden 是否显示隐藏文件和目录,默认值为 0 不显示隐藏文件
  • g:Lf_PreviewResult 设置需要显示预览的内容,默认值为全 1
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    let g:Lf_PreviewResult = {
    \ 'File': 1,
    \ 'Buffer': 1,
    \ 'Mru': 1,
    \ 'Tag': 1,
    \ 'BufTag': 1,
    \ 'Function': 1,
    \ 'Line': 1,
    \ 'Colorscheme': 1,
    \ 'Rg': 1,
    \ 'Gtags': 1
    \}

配置好了 LeaderF,在 vim/neovim 的命令行输入 :Leaderf tab 就可以看到相关的命令了,如果忘记了具体的命令也没有关系,使用 LeaderfSelf 即可列出所有的 Leaderf 命令。如何想查看具体命令的使用方法,在命令窗口输入 :Leaderf -h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
subcommands:

{file,tag,function,mru,searchHistory,cmdHistory,help,line,colorscheme,gtags,
self,bufTag,buffer,rg,filetype,command,window,quickfix,loclist,jumps}
file search files
tag navigate tags using the tags file
function navigate functions or methods in the buffer
mru search most recently used files
searchHistory execute the search command in the history
cmdHistory execute the command in the history
help navigate the help tags
line search a line in the buffer
colorscheme switch between colorschemes
gtags navigate tags using the gtags
self execute the commands of itself
bufTag navigate tags in the buffer
buffer search buffers
rg grep using rg
filetype navigate the filetype
command execute built-in/user-defined Ex commands.
window search windows.
quickfix navigate the quickfix.
loclist navigate the location list.

好了,我可以放弃 fzf.vim, ctrp.vim, tagbar, unite.vim, denite.vim 等一系列 vim 插件了。 在日常使用中,每次都输入那么长的命令不太方便,我们可以配置以下容易记忆的快捷键。

1
2
3
4
5
6
7
noremap <leader>fs :LeaderfSelf<cr>
noremap <leader>fm :LeaderfMru<cr>
noremap <leader>ff :LeaderfFunction<cr>
noremap <leader>fb :LeaderfBuffer<cr>
noremap <leader>ft :LeaderfBufTag<cr>
noremap <leader>fl :LeaderfLine<cr>
noremap <leader>fw :LeaderfWindow<cr>

值得一提的是 rg 命令,可以直接在目录文件内搜索字符串,ripgrep 的正则表达式比 vim 的正则要正常多了。vim 的正则表达式的用法可以参见:https://vimdoc.sourceforge.net/htmldoc/pattern.html
以前我为了规避 vim 的正则使用了一个插件 https://github.com/othree/eregex.vim 现在这个插件也不需要了。

要利用 LeaderF 调用 rg 命令,可以使用命令行 :Leaderf! rg, 为了方便使用使用下面的快捷键查询光标所在 word

1
nmap <leader>frb <Plug>LeaderfRgCwordLiteralBoundary

运行 LeaderF 之后的操作

在执行 Leaderf 命令弹出的界面后,需要使用特定的快捷键进行操作,这些快捷键可以使用 help leaderf-prompt 进行查看。

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
Once LeaderF is launched:                       *prompt* *leaderf-prompt*
<C-C>, <ESC> : quit from LeaderF.
<C-R> : switch between fuzzy search mode and regex mode.
<C-F> : switch between full path search mode and name only search mode.
<Tab> : switch to normal mode.
<C-V>, <S-Insert> : paste from clipboard.
<C-U> : clear the prompt.
<C-W> : delete the word before the cursor in the prompt.
<C-J>, <C-K> : navigate the result list.
<Up>, <Down> : recall last/next input pattern from history.
<2-LeftMouse> or <CR> : open the file under cursor or selected(when
multiple files are selected).
<C-X> : open in horizontal split window.
<C-]> : open in vertical split window.
<C-T> : open in new tabpage.
<F5> : refresh the cache.
<C-LeftMouse> or <C-S> : select multiple files.
<S-LeftMouse> : select consecutive multiple files.
<C-A> : select all files.
<C-L> : clear all selections.
<BS> : delete the preceding character in the prompt.
<Del> : delete the current character in the prompt.
<Home>: move the cursor to the begin of the prompt.
<End> : move the cursor to the end of the prompt.
<Left>: move the cursor one character to the left.
<Right> : move the cursor one character to the right.
<C-P> : preview the result.
<C-Up> : scroll up in the popup preview window.
<C-Down> : scroll down in the popup preview window.
  • tab : 切换输入模式和 normal 模式,进入 normal 模式后可以使用 jk 上下移动光标来查看文件。
  • q : normal 模式中,退出 LeaderF

在输入模式下,可以使用下面的快捷键进行分屏显示。

  • ctrl + x : 横向分割
  • ctrl + ] : 竖向分割
  • ctrl + T : tab 分割

☆ LeaderF + gtags 的配置

gtags 和 LeaderF 配置起来使用,实在是很不错。首先要配置好 gtags,关于 global 的安装详见 GNU Global 的使用,这里就不再详细说了,gtags 的配置添加下面两行即可。

1
2
let $GTAGSLABEL='native-pygments'
let $GTAGSCONF='/usr/local/share/gtags/gtags.conf'

配置好系统 gtags,global ,gtags.conf 的正确路径。

1
2
3
4
let g:Lf_Global = '/usr/local/bin/global'
let g:Lf_Gtags = '/usr/local/bin/gtags'
let g:Lf_Gtagsconf = '/usr/local/share/gtags/gtags.conf'
let g:Lf_Gtagslabel = 'native-pygments'

下面两行是配置gtags 自动生成 tags 文件,主要是三个文件 GPATH , GRTAGS GTAGS

1
2
let g:Lf_GtagsAutoGenerate = 1
let g:Lf_GtagsAutoUpdate = 1
  • g:Lf_GtagsAutoGenerate 是否自动生成 tags 文件。设置成 1 并且在 g:Lf_RootMarkers 定义的目录中,tags 会自动生成
  • g:Lf_GtagsAutoUpdate 是否自动更新 tags。如果设置成 0 ,需要先执行 Leaderf gtags --update 手动更新 tags 文件

tags 文件生成的目录和 g:Lf_CacheDirectory 的配置相关, g:Lf_CacheDirectory 用于设置缓存文件目录,默认的目录是 $HOME (Windows 上会有变化)使用 _ 替换了 /

1
2
ls ~/.LfCache/gtags/_home_henices_.vim 
GPATH GRTAGS GTAGS

完成了上面的配置后,我们就可以正常使用 LeaderF 来对 gtags 生成的 tags 文件进行浏览了,在命令行使用 :Leaderf gtags -h 可以看到详细的命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
:Leaderf gtags -h
usage:
Leaderf[!] gtags [-h] [--remove] [--recall]
Leaderf[!] gtags --update [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [--accept-dotfiles]
[--skip-unreadable] [--skip-symlink [<TYPE>]] [--gtagslibpath <PATH> [<PATH> ...]]
Leaderf[!] gtags [--current-buffer | --all-buffers | --all] [--result <FORMAT>] [COMMON_OPTIONS]
Leaderf[!] gtags -d <PATTERN> [--auto-jump [<TYPE>]] [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>]
[--append] [--match-path] [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [COMMON_OPTIONS]
Leaderf[!] gtags -r <PATTERN> [--auto-jump [<TYPE>]] [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>]
[--append] [--match-path] [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [COMMON_OPTIONS]
Leaderf[!] gtags -s <PATTERN> [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>] [--append]
[--match-path] [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [COMMON_OPTIONS]
Leaderf[!] gtags -g <PATTERN> [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>] [--append]
[--match-path] [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [COMMON_OPTIONS]
Leaderf[!] gtags --by-context [--auto-jump [<TYPE>]] [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>]
[--append] [--match-path] [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [COMMON_OPTIONS]
[COMMON_OPTIONS]: [--reverse] [--stayOpen] [--input <INPUT> | --cword]
[--top | --bottom | --left | --right | --belowright | --aboveleft | --fullScreen]
[--nameOnly | --fullPath | --fuzzy | --regexMode] [--nowrap] [--next | --previous]

...

LeaderF gtags 最常用的 :Leaderf[!] gtags -d/-r/-s/-g, 具体的作用如下所示,! 表示直接进入 normal 模式。

1
2
3
4
5
6
7
8
9
--gtagslibpath <PATH> [<PATH> ...]
Specify the paths to search for library functions.
-d <PATTERN>, --definition <PATTERN>
Show locations of definitions.
-r <PATTERN>, --reference <PATTERN>
Show reference to a symbol which has definitions.
-s <PATTERN>, --symbol <PATTERN>
Show reference to a symbol which has no definition.
-g <PATTERN>, --grep <PATTERN>

日常使用中,同样可以配置快捷键方便使用,下面的快捷键将对光标所在单词进行 tag 查找。

1
2
3
4
nmap <leader>fgd <Plug>LeaderfGtagsDefinition
nmap <leader>fgr <Plug>LeaderfGtagsReference
nmap <leader>fgs <Plug>LeaderfGtagsSymbol
nmap <leader>fgg <Plug>LeaderfGtagsGrep

运行 LeaderF gtags 之后

使用 LeaderF + gtags 跳转到源码后,如果想继续跳转到下一个或者上一个 tag 可以使用 Leaderf gtags --nextLeaderf gtags --previous

1
2
3

noremap <leader>fgn :<C-U><C-R>=printf("Leaderf gtags --next %s", "")<CR><CR>
noremap <leader>fgp :<C-U><C-R>=printf("Leaderf gtags --previous %s", "")<CR><CR>

☆ LeaderF 的其他用法

LeaderF 还可以和 Gutentags 配合使用进行源码浏览,但已经超出本文内容,有兴趣者可以查阅网络上的其他资料。

☆ 参考资料

https://github.com/Yggdroot/LeaderF/blob/master/doc/leaderf.txt
https://retzzz.github.io/dc9af5aa/
https://github.com/Yggdroot/LeaderF/blob/master/README.md
https://zhuanlan.zhihu.com/p/36279445
https://github.com/vim/vim/blob/master/runtime/doc/popup.txt
https://neovim.io/doc/user/api.html#api-floatwin

对话logseq联合创始人,看硅谷大佬的传奇投资 总结

https://pca.st/x398eeq0

  1. 技术招聘时,有 side project 的优先,认为有 side project 的技术人员大多有自己独特的想法,自驱力也较强。
  2. 强调技术热情和学习能力,小众语言会的人不多,但是语言不是主要问题。对于对新技术充满热情和好奇心的技术人来说学习就可以了。
  3. 自由开放的团队文化,大都是技术人员,相互之间比较平等,和社区沟通交流紧密。没有明确的 deadline,但大家都比较努力,工作任务分配以兴趣自领为主指派为辅。
  4. 没有太多的营销,产品定位和路线也是逐渐明确,最开始是从秦天生的一个 side project 慢慢发展起来。也没有定量分析过产品用户爆炸性增长的原因,只有模糊的感觉,Logseq 内置 PDF 阅读和标注感觉是一个突破点。
  5. Logseq 团队关于远程工作的一些实践,志远认为在一个国际团队中远程工作需要克服时差问题,需要讨论问题的时候比较麻烦。解决的方式是写比较详细的 issue 复现文档,基本是 step by step 的。讨论想法多录制一些演示视频,有问题就直接给对方发消息不能马上回复也问题不大,很多事情没有想象中的重要。
  6. Logseq 团队协作的主要工具,代码问题和 issue 管理使用 Github,问题讨论使用 Discord + 论坛 (Discord 处理即时反馈,论坛主要用来较长时间的讨论), 团队内部的通讯工具使用 Slack。

Logseq 的投资人非常豪华,我查了一下有 Stripe 首席执行官 Patrick Collison、GitHub 前首席执行官 Nat Friedman、Shopify 创始人 Tobias Lütke、A16Z 总经理 Sriram Krishnan等人,更神奇的是他们大多也是 Logseq 的用户。

听完这期博客,我感觉陈志远是非常纯粹的技术人员,谦逊内敛,对技术充满热爱,喜欢用技术解决现实生活中的问题。坚持自己的产品定位,不浮躁不傲娇,长期认真地完善产品功能,不为短期的生存而感到焦虑,这或许就是小而美的团队的优势吧。