Using Kickstart.NeoVIM

一直不是 LSP(Language Server Protocol)的粉丝,总觉得配置比较麻烦,但最近 试用了 kickstart.nvim,LSP 开箱可用,感觉还是有一些帮助的。

kickstart.nvim 简介

kickstart.nvim 是一个单文件的 Neovim 配置文件,包含大量注释和最常用的插件配置。 最方便的在于可以自动安装缺失的插件。只要网络环境允许,安装了它的配置文件之后, 只要启动 nvim 就可以自动完成后续的配置。项目地址:kickstart.nvim

初使用

在安装了 kickstart.nvim 之后,立刻做了一些自己习惯键位的设置,并调整了部分插件, 的确感觉比较省心。我做的修改可以在我的 github 中找到:my nvim config

日常维护

插件系统使用 Lazy.nvim,需要更新插件的时候可以执行 :Lazy,根据菜单可以选择更新(Update)、 清理(Clean)等等。LSP 使用 Mason.nvim,也可以执行 :Mason 看到类似的菜单。

主要用法

一个对新手很有帮助的插件是 which-key.nvim,可以通过浮动窗口提示可用的命令按键。 比如在命令状态下按下 g 键,它就会提示你后续可以按的按键,下面代码是部分提示内容:

d -> LSP: [G]to [D]efinition
D -> LSP: [G]to [D]eclaration
I -> LSP: [G]to [I]mplementation

LSP 的功能也比较强大,比如可以在整个工程内进行变量改名:<leader>rn,还有一个是 Code Action, 通过 <leader>ca 启动,具体能实现的功能由 LSP 本身来决定。

LSP 配置

不同 LSP 的配置还不同。比如在使用 lua_ls 的时候,用 Code Action 功能关闭了对某个建议的提示, 后续找了半天没有找到从哪里恢复设置。结果最后发现保存在了 ~/.config/.luarc.json 这个文件中。 而 pylsp 的设置需要在 nvim 的配置文件中进行修改。具体其它一些用法还要在将来逐渐领会。

Font Fallback

让终端可以显示的更美观。

字体问题

只从更换到 alacritty 作为主要的终端模拟器之后,一直对它很满意,唯一遇到的问题是部分字形无法 显示,例如 💻 是一个电脑的图标,但在我之前的终端上显示不出来。但这种字形平时很少遇到,网页 上显示也都正常,就一直没有管它。究其根源就是这些字形在我目前使用的字体文件中没有定义,所以 无法显示。

字体 Fallback

最近又试用了 ghostty,它却可以正常显示这些字形,于是萌生了提升 alacritty 体验的想法。经过调研 发现 alacritty 没有字体 fallback 的设置,只能依赖系统的设置。解决的办法就是创建一个字体配置文件: .config/fontconfig/fonts.conf,内容如下:

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
  <alias>
    <family>JetBrains Mono</family>
    <prefer>
      <family>JetBrains Mono</family>
      <family>Noto Color Emoji</family>
     </prefer>
  </alias>
    <alias>
    <family>JetBrains Mono Bold</family>
    <prefer>
      <family>JetBrains Mono Bold</family>
      <family>Noto Color Emoji</family>
    </prefer>
  </alias>
    <alias>
    <family>JetBrains Mono Italic</family>
    <prefer>
       <family>JetBrains Mono Italic</family>
      <family>Noto Color Emoji</family>
    </prefer>
  </alias>
</fontconfig>

这里定义了我如果使用 JetBrains Mono 字体的时候,如果遇到不能显示的字形,就要使用 Noto Color Emoji 字体来显示。设置之后重启 alacritty 就可以正确显示之前缺失的字形了。

存在的问题

  • Noto Color Emoji 是我为了这次调整新安装的字体,不知道有什么办法可以知道 ghostty 使用的什么字体,ghostty 甚至不依赖系统的字体设置。
  • alacritty 对字体的 ligature 没有支持,ghostty 支持的就很好。

Dual boot voidlinux from cloud

云平台上并没有 void 的镜像,本文记录如何在一个新安装的 arch 云主机上,安装并配置 void。

文件系统准备

在 arch 主机上使用的是 btrfs 文件系统,这会大大简化分区操作。首先看一下当前配置:

pluto@arch4 ~ > sudo btrfs su l /
ID 256 gen 126 top level 5 path var/lib/portables
ID 257 gen 126 top level 5 path var/lib/machines
ID 258 gen 61 top level 5 path swap

前面两个应该是 systemd 建立,目前都是空的,swap 是虚拟内存空间,需要保留。 由于还准备保留 arch,双系统共用 home 会比较方便,所以建立一个 home 子卷。

pluto@arch4 ~ > sudo btrfs su cr /@home
Create subvolume '//@home'
pluto@arch4 ~ > sudo cp /home/* /@home/ -a

然后设置 /etc/fstab 挂载 home 分区,添加如下内容:

UUID=<your-btrfs-device-uuid> /home btrfs subvol=@home,defaults 0 0

注意如果 /home 目录的权限是 700 的话,普通用户无法访问个人目录,需要改成 755。

重新生成启动配置文件,检查生成的文件是否合理:

pluto@arch4 / > sudo grub-mkconfig -o /boot/grub/grub.cfg

接下来把 arch 的 文件系统做个快照,以后作为 arch 的根目录,同时建立一个 void 的根目录。

pluto@arch4 / > sudo btrfs su sn / /@archroot
Create snapshot of '/' in '//@archroot'
pluto@arch4 / > sudo rmdir @archroot/@home
pluto@arch4 / > sudo btrfs su cr /@voidroot
Create subvolume '//@voidroot'

重启后确认文件系统挂载没有问题,删除原来根文件系统中的内容:

pluto@arch4 / > sudo mount /dev/sda3 /mnt
pluto@arch4 ~ > sudo find /mnt -mindepth 1 -maxdepth 1 ! -name '@archroot' ! -name '@home' ! -name '@voidroot ! -name swap -exec rm -rf {} +

此时必须重新安装一下 grub,否则可能进入到 grub rescue 模式(刚刚犯了这个错误)

pluto@arch4 ~ > sudo grub-install --efi-directory=/efi

安装 void

重启进入 arch 之后,挂载 @voidroot 目录:

pluto@arch4 ~ > sudo mount /dev/sda3 /mnt -o subvol=@voidroot

按照官方安装文档安装 void。 需要注意的主要有以下几项:

  1. 允许 dhcpd 和 sshd 两个服务,否则重启之后可能无法连上主机。
bash-5.2# ln -s /etc/sv/dhcpcd /etc/runit/runsvdir/default/
bash-5.2# ln -s /etc/sv/sshd /etc/runit/runsvdir/default/
  1. 不重复安装 grub,使用 arch 的启动管理器,在 /etc/grub.d/40_custom 中 填入如下内容。
menuentry 'Void Linux' {
    set root='hd0,gpt3'
    linux /@voidroot/boot/vmlinuz-6.6.59_1 root=UUID=<your-btrfs-device-uuid> rw rootflags=subvol=@voidroot  loglevel=3 quiet console=tty0 console=ttyS0,115200
    initrd /@voidroot/boot/initramfs-6.6.59_1.img
}
  1. 由于共享 home 分区,添加用户,注意 uid 和 gid 是否相同。
  2. 注意用户的 sudoer 设置,使用户可以获得 root 权限。
  3. 双系统使用不同的 ssh key 会让客户端很麻烦,因此将 arch 系统中的 key 复制到 void 系统中。
  4. void 更新了内核之后需要更新 grub 的配置。

使用

在 arch 系统中,可以使用

sudo grub-reboot 'Void Linux'

来让系统在重启之后进入到 void 系统。但由于文件系统是 btrfs,grub 无法直接修改,使得之后每次 启动都会在 void 系统中。解决方法是在 void 中安装 grub 工具,不执行 grub-install 安装。 然后用 grub-editenv 修改 arch 的启动设置。

pluto@void ~ > sudo mount /dev/sda3 -o subvol=@archroot /mnt
pluto@void /mnt/boot/grub > grub-editenv grubenv set next_entry='Arch Linux'

这样就可以在重启后进入 arch 系统。

using ffmpeg to stablize a video

手持拍摄的视频总会抖动,使用 Linux 的现成工具就可以进行修补。

首先将视频转换为图像文件:

$ ffmpeg -i ../INPUT.MP4 DSC_%03d.png

从图像中找到一个子图像用来对比,尽量小一点的图像便于快速定位,但必要要保证 图像有一定的特点,可以在视频中唯一定位。

接下来利用 ImageMagick 进行子图像的定位:

$ compare -metric RMSE -subimage-search big.png sub.png k.png

其中命令中的最后一个参数是具有定位信息的结果图像,在这里可以忽略。

编写一个简单的命令脚本将每次的定位结果写入到文件中:

$ for i in DSC_* ; do compare -metric RMSE -subimage-search $i sub.png k.png 2>> log.txt; echo >> log.txt; done
$ cat log.txt | awk '{print $4}' > pos.txt

pos.txt 中的坐标值就是子图像在每个视频帧的位置,然后编写一个小脚本对视频帧进行 剪裁。这里我用了 python 以增加扩展性,也许将来可以把全部内容写到一个程序中。

最后用 ffmpeg 将图像再编码成视频。

$ ffmpeg -f image2 -i pic%03d.png test.mp4

peek into my mifare card

校园一卡通是 Mifare 卡,一直想了解它的原理……

入手 ACR122U 读卡器

MIFARE 是 NXP 公司的商标,主要用于利用 NFC 技术通信的低成本ID/IC卡。 网上找相关标准比较复杂,还是从工程的角度入手。淘宝购入 ACR122U 芯片 的读卡器,然后用相关软件对卡进行操作来增加对卡的认识。

读卡器到手之后在 Linux 下面无法正常工作,dmesg 显示错误消息:

NFC: Couldn't poweron the reader (error -11)

以为是内核的问题,更新了 Debian 到最新版之后问题依旧。

安装驱动和软件

换个思路,在 ACS 下载了最新的驱动,并安装相关软件:

# dpkg -i libacsccid1_1.1.5-1~bpo9+1_amd64.deb
# apt-get install pcscd pcsc-tools

结果运行 pcsc_scan 之后,读卡器的红灯亮起,竟然开始工作了。 不过这个软件读到的只是卡的属性,并看不到具体的数据,继续安装了 nfc 软件

# apt-get install libnfc5 libnfc-bin libnfc-dev

使用 nfc-list 也只能读到ATQA(属性),UID(第一扇区前四个字节)和SAK(?)。

暴力破解

还需要下载一个强力的软件 mfoc,通过暴力破解获取数据。下载源码编译之后,运行

# ./mfoc -O mycard.mfd

就可以将数据完整读出了,但由于是暴力破解,所以需要的时间比较长。感觉 读一张卡片要 10 分钟左右,比 Windows 下面的软件要快一些,也更加稳定。

mfoc 读出数据的过程也把密钥获得了,将密钥保存到文件中,下次读卡的时候就会 快一些:

# ./mfoc -f keys.txt -O mycard.mfd

目前还有一个疑问,不同的校园卡用的密钥竟然不一样,这样如何管理呢?也许 密钥不唯一,暴力破解的时候就有可能得到不同的值,实际密钥会是不同的一个。

另外如果用校园卡做门禁,只要用到 UID 部分就可以,也不需要破解,速度很快。

using pandoc to convert latex to docx

由于我比较习惯使用 latex 写自己的各种文档,而提交的时候又往往需要 Word 格式, 有一个合适的转换器就变得非常必要了。

简介

将 latex 转换成 Word 格式的需求不断涌现,印象比较深的是 2011 年提交文稿的那次。 当时也是找了很多工具,最后使用了 tex4ht 工具,将文稿转换为 html,然后用自己 写的一些过滤脚本进行处理,最后才导入 Word。整个过程是比较痛苦而且错误百出的, 结果直到今天依然没有非常理想的工具。

最近又有了难以躲过的转换格式需求,pandoc 软件进入了我的视野,通过查看手册 发现 pandoc 简直是一个万能转换器,而我只是尝试了对 doc 的支持。

初使用

用它转换文件格式非常容易,不用配置脚本也没有复杂的开关选项。对于转换 latex 到 docx 只要如下的命令:

$ pandoc -f latex -t docx source.tex -o output.docx

不用解释就可以了解这个命令的使用方法,而且给我的第一感觉就是非常的快,甚至 比使用 latex 生成 pdf 文件的速度还快。唯一发现的问题是表格支持不太好,但表格 在我的文档中使用不多,手动调整一下就好了。

转换论文

这次的主要任务是转换科技论文,pandoc 又一次给我了惊喜,大部分公式和图片都 很好的进行转换,只有几个问题需要关注:

  1. pdf 格式的文件支持不好,必须先转换为 png 格式。
  2. matrix 公式支持不好
  3. 公式里面自定义的 argmax 命令不支持
  4. 公式和图没有编号

感觉 pandoc 并没有使用 latex 作为后端,而是用自己的解释器来分析文档,因此 稍微复杂一些的 latex 指令就无法支持了。虽然还没有尝试,估计 pgf 系列包都 不会支持的很好。

没有编号的问题比较大,交叉引用全部都失效了,这次我都通过手工修改了。网上看到 好像有过滤器可以做类似的事情,但语法格式都不是标准的 latex,我就只好放弃了。

参考文献

我开始以为参考文献是不被支持的,结果一个简单的过滤器就可以解决一半问题。

$ sudo apt-get install pandoc-citeproc
$ pandoc -f latex -t docx source.tex --bibliography=mybib.bibtex -o output.docx

这样是可以生成参考文献,但是格式不符合要求。经过网络搜索才知道还需要一个 格式描述文件(citation style language)ieee.csl。下载这个文件之后用如下命令就可以 搞定参考文献了。

$ pandoc -f latex -t docx source.tex --bibliography=mybib.bibtex --csl=ieee.csl -o output.docx

Gizwits ESP8266

尝试一下机智云的软硬件环境

机智云

机智云是一个比较常用的物联网云平台,由于手上有相关的硬件,因此准备尝试一下。

GAgent

GAgent 是机智云的固件产品,写入到 ESP8266 wifi 模块后可以简化物联网 wifi 上网的主要功能。烧写固件需要到乐鑫(Espressif)下载工具软件,并从 机智云下载固件映像。按照机智云上的固件烧写说明却无法连接成功。由于我 用的模块来自第三方,猜想是 GPIO0 的管脚位置不同,最后查了淘宝上的一款 ESP-12F 模块,才知道我的 GPIO0 在从指示灯开始数的第五个位置。

第一次烧还是不成功,报 efuse 错误,结果第二次烧就成功了。

机智云串口调试助手

使用调试助手和 wifi 模块连接上之后,点击模拟 V4MCU,则可以自动和 wifi 模块 通过串口协议通信。输入 product_key 之后,可以在界面上看到我在机智云上建立 的产品信息。

在手机端安装上机智云的产品调试 APP(登录有问题,用我注册的个人用户帐号好像 无法登录,不过可以跳过登录,不影响使用),在调试助手中打开指令界面,选择 AirLink按钮,然后在手机端输入 AP 的信息并搜索硬件。大概十几秒之后 wifi 模块就可以登录机智云了,在手机段也可以看到我的产品信息。

手机软件根据我设置的产品信息可以看到照明的按钮,我在手机上对这个按钮进行 操作就可以在调试助手中看到照明的数值被改变了,也就是基本实现了我所需要 的功能。

连接 Arduino

使用 Arduino 连接到串口 wifi 模块,比较麻烦的是每次下载代码必须把 wifi 模块拿掉,否则会干扰下载。按照示例的代码下载了之后,从 DEV 到 APP 的通道 没有问题。但从 APP 到 DEV 就是不行。通过机智云网上的日志可以看到,消息传递 没有问题,应该就是 Arduino 这边的代码问题了。

后来把检测是否有相关命令的 hasBeenSet 调用去掉,直接用 read 读取相应的值, 结果就正常了。顺便说一下机智云自带的调试 APP 和下载参考代码生成的 APP 都可以用,功能类似。(3月17日更新:这个部分后来发现还是我自己的代码问题)

写入 AT 固件

后来想在 ESP8266 模块中写入 AT 固件,自己控制 WIFI 接入,但确多次无法成功。 网上下载的不同固件都无法正常启动,在 minicom 中只能看到乱码。后来看资料 指导启动信息的波特率是 74880,minicom 和 screen 都不支持,最后还是 esptool 中带的 miniterm.py 支持。

看到的错误原因是 csum err,但 verify_image 也没有问题,不知道原因是什么。 网上看到有人说用 dout 方式写入就没有问题了,可用 win 下面的官方写入软件 根本就写不进去,最后下载开源的 esptool 就可以用 dout 方式写入了,结果看到 错误信息不一样了,变成

2nd boot version : 1.7(5d6f877)
SPI Speed : 40MHz
SPI Mode : DOUT
SPI Flash Size & Map: 32Mbit(512KB+512KB)
jump to run user1 @ 1000

mismatch map 5,spi_size_map 4
system_partition_table_regist fail

还是看网上的信息,说 1.7 的固件会有这个问题,但 1.6.2 的就没有问题了。 真是历尽千辛万苦终于获得了 ready 提示信息。

虽然记录的过程看来很简单,但实际经过的尝试复杂的多。

总结

总体感觉机智云上手还是比较容易的,从昨天看资料开始,全部用掉的时间估计在 4 个小时左右。要不是软件这边有一点坑,应该更快的可以完成设计。

Play with android

Google 现在好像不太支持命令行工具了,android 命令即将废弃,好像 已经没有办法只用命令行工具完成 Android 开发了。

安装 SDK

只安装了 SDK 之后其实离开始工作还有很大距离。运行 sdkmanager --list 可以看到能安装的组件,然后就可以用 sdkmanager 安装,例如

$ sdkmanager "emulator;platform-tools"

建立虚拟机

建立虚拟机可以用 avdmanager 命令,例如:

$ ./avdmanager create avd -n test2 -k "system-images;\
android-25;google_apis;arm64-v8a" -d "Galaxy Nexus"

其中 -d --device 参数在手册里面都没有提,在执行 create avd 命令的时候可以看到相关的提示。而可选的设备列表在 lib/devices.xml 文件中可以找到。

启动虚拟机

$ ./emulator -avd test2

这个命令在执行的时候有可能报告 libGL 的加载失败,可以在运行前指定:

$ export ANDROID_EMULATOR_USE_SYSTEM_LIBS=1

建立新工程

原来的 android create project 命令已经不被支持,目前只能使用 android studio 建立工程。

Install Debian

给实验室的电脑装 Debian,记录几个遇到的问题

Debian 本来是非常熟悉了,但安装 stretch 的时候还是需要的几个问题

网络接口名称

新安装的系统使用了新的命名规则,例如网络接口的名字变成了 enp0s31f6 这样就变得很不习惯,暂时没有发现这样的好处(命名唯一)。 可以使用 udev rule 来给接口改名字,但比较简单的还是增加一个内核参数, 修改 /etc/default/grub

GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"

保存上次启动选项

当使用多系统的时候,可以保存上次的选项会比较方便,这里只是记录一下 方法,并不是很困难,还是修改 grub 文件

GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT=true

ip 命令

ifconfig 命令缺省不安装了,取而代之的是功能更加强大的 ip 命令, 但这个命令还需要熟悉,如果要安装原来的命令,需要

$ sudo apt-get install net-tools

下面列出一些常用命令,便于以后记忆:

$ sudo ip addr add 192.168.0.51/24 dev eth0
$ ip addr show eth0
$ ip link
$ ip route show
$ sudo ip route add default via 192.168.0.1
$ ip neighbour  # arp -a
$ sudo ip link set eth0 down

Install Windows10

给实验室的电脑装 Windows,记录几个遇到的问题

安装 Windows 过程本身没有什么问题,但也许是太长时间没有用过 Windows 系统,后续安装软件和配置的时候遇到了一些问题。

无法运行下载应用

系统安装完毕后需要运行激活客户端进行 KMS 激活,结果相关软件 确“无法运行”。结果是我太着急了,如果多等待一会就可以看到是 SmartScreen 把应用拦截了,由于网络还没有配置所以迟迟给不出 建议。解决方法要么关掉 SmartScreen,要么配置好网络。

系统自动下载应用

这是一个迷惑我很久的问题。在实验室里面安装的一个 Windows 加上必备应用占用空间 30G 左右。而在我办公室安装的同样配置 竟然要多占用几个 G 的空间。过了几天我才发现,原来是办公室 的网络环境好,自动下载了 N 个应用,包括游戏和一些垃圾软件。 卸载之后应该就没有问题了。网上资料显示,如果要防止自动安装, 可以增加如下注册表项:

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent]
"DisableWindowsConsumerFeatures"=dword:00000001

使用 UTC 时间

部分电脑需要 Windows 和 Linux 共存,系统时间就成为影响使用 体验的一个麻烦。最好的办法还是让 Windows 使用 UTC 时间,也是要 修改注册表:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation]
"RealTimeIsUniversal"=qword:00000001

关于杀毒软件

这个部分的看法有分歧,官方和国外好多地方都说有了 WindowsDefender 就不需要安装杀毒软件了。但这里我持保留态度,主要对微软不是很信任, 因此还是安装了 ESET,希望更专业一些。安装了 ESET 后 WindowsDefender 的杀毒功能就自动关闭了,应该也不会影响性能。