BNU-FZH

fengzhenhua@outlook.com

前言:

EOFEnd Of File的缩写,表示自定义终止符。既然自定义,那么EOF就不是固定的,可以随意设置别名,意思是把内容当作标准输入传给程序,Linux中按Ctrl-d就代表EOF

Shell中我们通常将EOF<< 结合使用,表示后续的输入作为子命令或子Shell的输入,直到遇到EOF为止,再返回到主调Shell。回顾一下<<的用法,当Shell看到<<的时候,它就会知道下一个词是一个分界符。在该分界符以后的内容都被当作输入,直到Shell又看到该分界符(位于单独的一行)。这个分界符可以是你所定义的任何字符串。

用法:

1
2
3
<<EOF        //开始
....
EOF //结束

也可以自定义,如:

1
2
3
<<FFF        //开始
....
FFF //结束

注意:

第一个EOF必须以重定向字符<<开始,第二个EOF必须顶格写,否则会报错。如果将开始处的<<切换为<<-, 则结束分界符EOF前有制表符或者空格,则EOF此时仍然被当做结束分界符,此时EOF不必顶格写。

EOF配合cat能够进行多行文本输出。

通过cat配合重定向能够生成文件并追加操作,在它之前先回顾几个特殊符号:

1
2
3
4
<   :输入重定向
> :输出重定向
>> :输出重定向,进行追加,不会覆盖之前内容
<< :标准输入来自命令行的一对分隔号的中间内容

例:

1
2
3
4
5
6
7
[root@localhost ~]# cat <<EOF   //运行后会出现输入提示符">"
> Hello
> wolrd
> EOF
输入结束后,在终端显示以下内容:
Hello
wolrd

1. 向文件file1.txt中输入内容

1
2
3
4
5
6
7
8
9
10
[root@localhost ~]# cat >file1.txt <<EOF
> aaa
> bbb
> ccc
> EOF

[root@localhost ~]# cat file1.txt
aaa
bbb
ccc

追加内容至file1.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@localhost ~]# cat >>file1.txt <<EOF
> 111
> 222
> 333
> EOF

[root@localhost ~]# cat file1.txt
aaa
bbb
ccc
111
222
333

覆盖file1.txt

1
2
3
4
5
6
[root@localhost ~]# cat >file1.txt <<EOF
> Hello wolrd
> EOF

[root@localhost ~]# cat file1.txt
Hello wolrd

2. 自定义EOF

1
2
3
4
5
6
7
8
[root@localhost ~]# cat >file1.txt <<FFF
> test
> hello
> FFF

[root@localhost ~]# cat file1.txt
test
hello

3. 编写一个脚本,生成mysql配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@localhost ~]# vim /root/test.sh
#!/bin/bash
cat >/root/EOF/my.cnf <<EOF
[client]
port=3306
socket=/usr/local/mysql/var/mysql.sock
basedir=/usr/local/msyql/
datadir=/data/mysql/data
pid-file=/data/mysql/data/mysql.pid
user=mysql
server-id=1
log_bin=mysql-bin
EOF

[root@localhost ~]# cat /root/EOF/my.cnf //查看生成的mysql配置文件
[client]
port=3306
socket=/usr/local/mysql/var/mysql.sock
basedir=/usr/local/msyql/
datadir=/data/mysql/data
pid-file=/data/mysql/data/mysql.pid
user=mysql
server-id=1
log_bin=mysql-bin

4. 编写脚本向mysql数据库建表、赋值并查询

1
2
3
4
5
6
7
8
9
10
[root@localhost ~]# vim eof.sh
#!/bin/bash
mysql -uroot -p123456 <<EOF
use test;
create table data(name varchar(15),age int,address varchar(25));
desc test.data;
insert into data values("tom",23,"china");
select * from data;
exit
EOF

4.1 运行脚本查看执行结果

1
2
3
4
5
6
7
8
9
[root@localhost ~]# bash eof.sh    //运行脚本,查看数据库中信息
mysql: [Warning] Using a password on the command line interface can be insecure.
Field Type Null Key Default Extra
name varchar(15) YES NULL
age int(11) YES NULL
address varchar(25) YES NULL

name age address
tom 23 china

4.2 在数据库中查看新增的数据:

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
30
31
32
33
34
35
36
[root@localhost ~]# mysql -uroot -p123456
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+

mysql> use test;

mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| data |
+----------------+

mysql> desc test.data;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| name | varchar(15) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| address | varchar(25) | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+

mysql> select * from data;
+------+------+---------+
| name | age | address |
+------+------+---------+
| tom | 23 | china |
+------+------+---------+

5. EOF中的变量处理

在使用cat EOF中出现$变量通常会直接被执行,显示执行的结果。若想保持$变量不变需要使用 \ 符进行注释 . 当存在$变量过多,或存在赋值命令的时候可直接在EOF上加上双引号就行。

EOF处理变量
1
2
3
4
5
6
7
8
9
10
11
cat << "EOF" > ~/.gitconfig
# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
# Initialization code that may require console input (password prompts, [y/n]
# confirmations, etc.) must go above this block; everything else may go below.
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
source /usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh
source /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
source /usr/share/zsh-theme-powerlevel10k/powerlevel10k.zsh-theme
EOF

简介

ping (Packet Internet Groper)是一种因特网包探索器,用于测试网络连接量的程序。Ping是工作在 TCP/IP网络体系结构中应用层的一个服务命令, 但是缺点很明显,不够直观。可使用gping继续替代。gping是一个跨平台的命令行程序,当您尝试ping主机或网站时,该程序会在终端内部显示漂亮的图形。

github地址

https://github.com/orf/gping

安装方式

install gping
1
sudo pacman -S gping

使用方式

1
2
gping --help #查看帮助文档
gping -V #查看版本信息

实际运用

1
gping www.google.com
gping

取代ping

~/.zshrc
1
alias ping="gping"

这个简单的 ls 命令列出目录的内容十分方便,但是直到我发现 exa 之前从来没想过会有命令能替代它。

exa 命令简介

exa 是一个命令行工具,可以列出指定路径(如未指定则是当前目录)的目录和文件。这也许听起来很熟悉,因为这就是 ls 命令所做的事情。

exa 被视作从 UNIX 旧时代延续至今的古老的 ls 命令的一个现代替代品。如其所声称的那样,它有比 ls 命令更多的功能、更好的默认行为。

exa 功能

以下是一些你应该使用 exa 替代 ls 的原因:

  • exals 一样可移植(在所有主流 Linux 发行版、*BSD 和 macOS 上可用)
  • 默认彩色输出
  • exa 不同格式化的“详细”输出也许会吸引 Linux/BSD 新手
  • 文件查询是并行进行的,这使得 exals 的性能相当
  • 显示单个文件的 git 暂存或未暂存状态

exa 的另外一个不同的地方是它是用 Rust 编写的。顺便说一句,Rust 与 C 语言的执行速度相近,但在编译时减少了内存错误,使你的软件可以快速而安全地执行。

在 Linux 系统上安装 exa

exa 最近很流行,因为许多发行版开始将其包括在其官方软件库中。也就是说,你应该可以使用你的 [发行版的包管理器] 来安装它。

从 Ubuntu 20.10 开始,你可以使用 apt 命令来安装它:

1
sudo apt install exa

Arch Linux 已经有了它,你只需要 使用 pacman 命令即可:

1
sudo pacman -S exa

如果它无法通过你的包管理器安装,请不要担心。毕竟它是一个 Rust 包,你可以很容易地用 Cargo 安装它。请确保在你使用的任何发行版 或 Ubuntu 上安装了 Rust 和 Cargo

安装 Rust 和 Cargo 后,使用此命令安装 exa

1
cargo install exa

使用 exa

exa 有很多命令选项,主要是为了更好的格式化输出和一些提高舒适度的改进,比如文件的 git 暂存或未暂存状态等等。

下面是一些屏幕截图,展示了 exa 是如何在你的系统上工作的。

简单地使用 exa 命令将产生类似于 ls 但带有颜色的输出。这种彩色的东西可能没有那么吸引人,因为像 Ubuntu 这样的发行版至少在桌面版本中已经提供了彩色的 ls 输出。不过,ls 命令本身默认没有彩色输出。

1
exa
exa 命令的输出截图,没有任何额外的标志

请注意,exals 命令的选项不尽相同。例如,虽然 -l 选项在 exals 中都给出了长列表,但 -h 选项添加了一个列标题,而不是 ls 的人类可读选项。

1
exa -lh
正如我之前提到的,exa 有列标题以获得更好的“详细”输出

我前面说过,exa 已经内置了 Git 集成。下面的屏幕截图给出了 –git 标志的演示。请注意 test_filegittracked 列中显示 -N ,因为它尚未添加到存储库中。

1
exa --git -lh
演示 git 标志如何与 exa 一起工作

下面的例子不是我的猫键入的。它是各种选项的组合。exa 有可供你尝试和探索的很多选项。

1
exa -abghHliS

你可以通过在终端中运行以下命令来获取完整的选项列表:

1
exa --help

但是,如果你想了解 exa 所提供的功能,可以查看其 Git 存储库 上的 官方文档。值得从 ls 切换到 exa 吗?

对于类 UNIX 操作系统的新手来说,exa 可能是用户友好的,它牺牲了在脚本中容易使用的能力,以换取“易用性”和外观。其中,显示得更清楚并不是一件坏事。

无论如何,ls 就像通用命令。你可以将 exa 用于个人用途,但在编写脚本时,请坚持使用 ls。当预期输出与任一命令中的实际输出不匹配时,ls 和 exa 之间一个 [或多个] 标志的差异可能会让你发疯。

我想知道你对 exa 的看法。你已经尝试过了吗?你对它的体验如何?

但是,如果你想了解 exa 所提供的功能,可以查看其 Git 存储库 上的 官方文档

值得从 ls 切换到 exa 吗?

对于类 UNIX 操作系统的新手来说,exa 可能是用户友好的,它牺牲了在脚本中容易使用的能力,以换取“易用性”和外观。其中,显示得更清楚并不是一件坏事。

无论如何,ls 就像通用命令。你可以将 exa 用于个人用途,但在编写脚本时,请坚持使用 ls。当预期输出与任一命令中的实际输出不匹配时,lsexa 之间一个 [或多个] 标志的差异可能会让你发疯。

我想知道你对 exa 的看法。你已经尝试过了吗?你对它的体验如何?

本文转自 exa:一个 ls 命令的现代替代品,如有侵权,请联系删除。

Zsh中实现快速路径跳转, 之前已经介绍了z.luaZsh配置快速路径跳转)。今天看到了另一个zsh的插件zoxide, 它是用rust语言写的,所以效率上应当是更高的。至于为什么会由z.lua切换到zoxide, 这里我也想不出更好的理由,但是大家可以参考文章zoxide VS z.luazsh-z VS zoxide, 今天我是做为尝试而切换到zoxide, 当然z.lua依然优秀。

zoxide 简介

zoxide is a smarter cd command, inspired by z and autojump.

It remembers which directories you use most frequently, so you can "jump" to them in just a few keystrokes.zoxide works on all major shells.

Getting started

1
2
3
4
5
6
7
8
9
10
11
12
z foo              # cd into highest ranked directory matching foo
z foo bar # cd into highest ranked directory matching foo and bar
z foo / # cd into a subdirectory starting with foo

z ~/foo # z also works like a regular cd command
z foo/ # cd into relative path
z .. # cd one level up
z - # cd into previous directory

zi foo # cd with interactive selection (using fzf)

z foo<SPACE><TAB> # show interactive completions (zoxide v0.8.0+, bash 4.4+/fish/zsh only)

Installation

install zoxide
1
sudo pacman -S zoxide

Configure

~/.zshrc
1
2
3
4
5
6
# set for zsh-z-git
# source /usr/share/zsh/plugins/zsh-z/zsh-z.plugin.zsh
# set for z.lua 功能上不如zsh-z-git完善
# eval "$(lua /usr/share/z.lua/z.lua --init zsh enhanced once)"
# set for zoxide instead of z.lua
eval "$(zoxide init zsh)"

对比配置信息来看,zoxide 好像更加简洁一些,但是这不是主要的切换依据,几个工具都可以尝试。我认为z.lua是从aur中安装的,但是zoxide是从Archlinux的官方仓库中安装,使用官方的工具我认为更可靠一些。

Import your data

If you currently use any of these plugins, you may want to import your data

autojump

Run this command in your terminal:

1
zoxide import --from=autojump "/path/to/autojump/db"

The path usually varies according to your system:

OS Path Example
Linux $XDG_DATA_HOME/autojump/autojump.txt or $HOME/.local/share/autojump/autojump.txt /home/alice/.local/share/autojump/autojump.txt
macOS $HOME/Library/autojump/autojump.txt /Users/Alice/Library/autojump/autojump.txt
Windows %APPDATA%\autojump\autojump.txt C:\Users\Alice\AppData\Roaming\autojump\autojump.txt
fasd, z, z.lua, zsh-z

Run this command in your terminal:

1
zoxide import --from=z "path/to/z/db"

The path usually varies according to your system:

Plugin Path
fasd $_FASD_DATA or $HOME/.fasd
z (bash/zsh) $_Z_DATA or $HOME/.z
z (fish) $Z_DATA or $XDG_DATA_HOME/z/data or $HOME/.local/share/z/data
z.lua (bash/zsh) $_ZL_DATA or $HOME/.zlua
z.lua (fish) $XDG_DATA_HOME/zlua/zlua.txt or $HOME/.local/share/zlua/zlua.txt or $_ZL_DATA
zsh-z $ZSHZ_DATA or $_Z_DATA or $HOME/.z
ZLocation

Run this command in PowerShell:

1
2
3
$db = New-TemporaryFile
(Get-ZLocation).GetEnumerator() | ForEach-Object { Write-Output ($_.Name+'|'+$_.Value+'|0') } | Out-File $db
zoxide import --from=z $db

介绍

各种规范指定文件和文件格式。此规范通过定义相对于哪些文件应该位于的一个或多个基本目录来定义应该查找这些文件的位置。

基本

XDG基本目录规范基于以下概念:

  • 有一个用于写入特定用户数据文件的基本目录。$XDG_DATA_HOME。
  • 有一个用于写入特定用户的配置文件基本目录。$XDG_CONFIG_HOME。
  • 有一组首选的基本数据目录。$XDG_DATA_DIRS。
  • 有一组首选的基本配置目录。$XDG_CONFIG_DIRS。
  • 有一个用于写入用户特定的非必要(缓存)数据的基本目录。$XDG_CACHE_HOME。
  • 有一个用户放置特定于用户的运行时文件和其他文件对象。$XDG_RUNTIME_DIR。

环境变量

XDG环境变量 默认值
$XDG_DATA_HOME $HOME/.local/share
$XDG_CONFIG_HOME $HOME/.config
$XDG_DATA_DIRS /usr/local/share/:/usr/share/
$XDG_CONFIG_DIRS /etc/xdg
$XDG_CACHE_HOME $HOME/.cache

$XDG_RUNTIME_DIR是用户特定的不重要的运行时文件和其他文件对象(例如套接字,命名管道…)存储的基本目录。该目录必须由用户拥有,并且他必须是唯一具有读写访问权限的目录。它的Unix访问模式必须是0700。

目录的生命周期必须绑定到登录用户。必须在用户首次登录时创建,如果用户完全注销,则必须删除该目录。如果用户多次登录,他应该指向同一目录,并且必须从第一次登录到他在系统上的最后一次登出时继续存在,而不是在两者之间删除。目录中的文件必须不能在重新启动或完全注销/登录循环后继续存在。

该目录必须位于本地文件系统上,不与任何其他系统共享。该目录必须完全按照操作系统的标准进行。更具体地说,在类Unix操作系统上,AF_UNIX套接字,符号链接,硬链接,适当的权限,文件锁定,稀疏文件,内存映射,文件更改通知,必须支持可靠的硬链接计数,并且对文件名没有限制应该强加字符集。此目录中的文件可能需要定期清理。为确保不删除您的文件,他们应至少每6小时单调时间修改一次访问时间戳记,或者在文件上设置“粘滞”位。

如果$XDG_RUNTIME_DIR未设置,应用程序应回退到具有类似功能的替换目录并打印警告消息。应用程序应使用此目录进行通信和同步,并且不应在其中放置较大的文件,因为它可能驻留在运行时内存中,并且不一定可以交换到磁盘。

参考规范

文件 参考规范:subdir应该为软件名
数据文件 $datadir/subdir/filename
配置文件 $confdir/subdir/filename

$config默认为~/.config : /etc
如果在尝试编写文件时,目标目录不存在,则应尝试使用权限创建目标目录0700。如果目标目录已存在,则不应更改权限。应用程序应准备好处理无法写入文件的情况,因为该目录不存在且无法创建,或者出于任何其他原因。在这种情况下,它可以选择向用户呈现错误消息。

参考文章

Emacs 是神的编辑器,而 Vim 是编辑器之神。二者为何会有如此美誉,且听本文向你一一道来。

0. 序章:神器的传说

在这个蔚蓝色的星球上,流传着两大神器的传说: 据说Emacs是神的编辑器,而Vim是编辑器之神。

追求独步天下的高手和低手们争着一睹它们的风采,可看到它们朴素单薄的界面后,不禁心下怀疑:这就是神器吗?甚至有人生了轻视之心。

肤浅的人嗤之以鼻,说:什么年代了,还抱着这么老土的玩意不放,真他妈Geek!同学,请冷静下来,听我说:它们的确够老了,都几十年的寿命了,但你想想为什么,为什么这么古老的编辑器,却有越来越多的人皈依它们。

Windows下用UltraEdit和Editplus的人质问:它们到底比UltraEdit和Editplus好在哪里?我说:不可同日而语。

连UltraEdit和EditPlus都没用过的同学问:它们就相当于Linux上的 Notepad吧?我说:请你从我的眼前消失。

一些人勇敢地拾起了Vim或Emacs,却发现学习曲线陡峭而漫长,于是在没发现它们的强大之前就放弃了,说:太难用了,把键盘当鼠标用的烂玩意,有什么好的?

还是有一些人留下来了,坚定地守护着这两大神器。一些说葡萄太酸的人想离开又不甘心,总是问:它们到底神在哪里啊?我不禁想起了李宗盛的几句歌词:

1
2
3
4
<span></span>有人问我你究竟是哪里好,
这么多年我还忘不掉?
春风再美也比不上你的笑,
没见过你的人不会明了。

也许你不会明了,我还是要努力讲一讲。

1. 无敌的可扩展性

1.1 可扩展性给了软件强大的生命

曾几何时,Windows用户对软件的可扩展性没有概念,他们只能对他们使用的软件进行非常有限的定制。扩展软件的权利保留在软件开发者手中。软件的使用者如果想要新的功能和特性,只能等待软件的升级。有能力的用户等不及了,为了添加自己想要的功能,从0开始写了一款新的软件。就这样,新的功能意味着新的软件,Windows下的软件前赴后继,迅速地更新换代着。因此,Windows下的软件都很短命。

Linux和开源软件渐渐流行起来,人们才发现:可扩展性才能给软件强大的生命。在MS的VS横行的今天,Eclipse为什么被评为最好的IDE?就是因为它在IDE中最具可扩展性。在IE几乎一统天下的时候,为什么Firefox能夺走越来越多的用户,也是因为它的可扩展性。提供了良好的扩展接口,用户自然会写出各种各样的插件,来满足用户自己形形色色的要求。这样,软件在用户的推动下自然变得强大了。

Emacs和Vim没有被时代淘汰,反而越发强大,也正是因为在数不清的编辑器中,他们具有无可匹敌的可扩展性。

1.2 Emacs是伪装成编辑器的操作系统

有句夸张的话说:Emacs是伪装成编辑器的操作系统。细细想来,这句话并不夸张。

Emacs其实是个Lisp的解释器,因此可以用Lisp灵活地扩展。Lisp是什么东西,这同样是种很有生命力的编程语言。在C语言还没有发明的年代,MIT的人工智能实验室写ITS操作系统时,一部分用的是汇编语言,还有一部分就是用的Lisp。现在,Lisp仍在人工智能研究领域广泛使用着。

有这么牛逼的扩展语言,注定Emacs向着无所不能的方向发展。渐渐地,人们用Emacs不再限于写程序,写文档,而且在Emacs里管理文件系统,运行终端,收邮件,上网,听音乐……,真是一发不可收拾。甚至,有人用Emacs控制咖啡机煮咖啡。

这种大而全的扩展,背离了“一个程序只做一件事并做好它”的Unix哲学,被Unix的忠诚用户所诟病。可是真的背离了吗?Emacs说过自己是一个编辑器吗?

正是因为Emacs的无敌的可扩展性,人们才分不清Emacs到底是不是一个编辑器了。但,就是有人喜欢这种All-in-One的哲学,喜欢在Emacs中完成每件事。所以才会有人写《生活在Emacs中》,所以,Emacs才会成为一种信仰。

1.3 Vim不只是Vi

Vim是Vi最受欢迎的变种之一,除了继承了Vi迅捷的编辑方式,Vim的功能已经比原始的Vi强大得多。这也得益于它可以用Vim脚本无限地扩展。Vim.org 上已经有数千个脚本了,给Vim增加各种各样的特性和功能。

为了证明Vim的可扩展性不输于Emacs,也有用户写了在Vim中玩游戏、运行Shell、和集成GDB在Vim内部调试的插件。客观地讲,Vim的脚本语言与Emacs的ELisp相比,略显逊色,但这丝毫不妨碍它把Vim扩展成非常优秀的编辑器。

说到底,Vim的前身Vi和Emacs的设计采用了不同的哲学,Vi更符合Unix传统,它通过管道机制和系统内各种积木工具打交道,它讲究的是和系统内的工具程序协作来完成用户的任务。和Emacs相比,它的定位很明确,就是要做一个强大的编辑器。因此Vim的绝大部分扩展,都是为了更好地完成编辑文本的任务。

海纳百川,有容乃大。Emacs和Vim通过别的编辑器无法比肩的可扩展性,不断吸收广大用户的智慧,是它们能成为“神器”的原因之一。

2. 特立独行的魅力

2.1 可扩展性让你倾注了灵魂

一旦你意识到Vim或Emacs的强大,你就踏上了不停发掘它们潜力的漫漫长路。你不停地改进自己的配置文件,你不停地搜索更好的插件,甚至有一天你开始动手写自己的插件。就像剑客保养自己的剑一样,你也甘心花时间提升你的Vim或Emacs。经年累月,不知不觉,你已经在那把剑上倾注了你的灵魂。

2.2 独特的操作方式让你中了毒

Emacs和Vim有着迥异的操作方式,却成了Unix/Linux世界中两种代表性的操作方式,有些软件的操作方式类似Vi,而有些软件的方式类似Emacs,甚至有些软件提供了Vi的键绑定和Emacs的键绑定让你选择。而无论哪种操作方式,对Windows用户来说都是古怪的。虽说古怪,多少代人也验证了这两种操作方式的高效。

Emacs号称Ctrl到死的编辑器。其实它几乎用了所有的辅助键,听说过没有,Emacs = Esc + Meta + Alt + Ctrl + Shift。所以高德纳大师说操作Emacs,就像弹奏管风琴。Emacs使用非常多的组合按键,这大概也是它高效于其它无模式编辑器的原因之一。你也可以定义自己的组合键序列,调用自己写的lisp函数,完成自己想要的功能。

Vi一向是以快速的文本编辑闻名于世的。它的按键更简洁,通常是单个字符按键,就实现某种操作。但这是以有模式为代价的。你要不停地按Esc在从它的插入模式返回Normal模式。客观得讲,在文本编辑方面,Vim比Emacs高效,因为它提供了一些Emacs没有对应功能的操作来辅助高效的文本编辑。但它的模式切换也让一些人受不了,于是那些人选择了Emacs。

不管你选择了Vim还是Emacs,你都要为习惯它们独特的操作方式而努力,这是一个技艺积累的过程。当你习惯了Vim或Emacs,你会有欲罢不能的感觉,你希望用它们完成尽可能多的任务,因为你再用别的编辑器也已经不习惯。

用Vim或Emacs就像吸食毒品,慢慢地就会上瘾。它们会带给你渐渐强烈的快感,但你也向它们献出了自己的灵魂。这时,你只能称它们为神器。

3. 黑客的编辑器

Vim的前身Vi的作者Bill Joy和Emacs的作者Richard Stallman都是那个时代著名的黑客,所以这两款编辑器一开始面向的主要用户就是写程序的人,现在仍然是。它们对编程加入了越来越多的支持,如语法高亮、智能缩进、关键字补全甚至集成调试。也有越来越多的程序员从IDE转向了Vim和Emacs。

用Vim和Emacs编程到底有什么好处?我想首先是它们高效的编辑操作会提高你的编程效率。其次你可以用它们完成各种语言的编程,所谓一剑在手,夫复何求。你不用再因为编程语言不同去学习不同的IDE的使用,那些庞大的IDE的升级换代也与你再不相关,你把精力用于学习编程语言本身就好了。听说Google和微软内部开发也都不用IDE的,他们也会用Emacs或Vim。

因为我写的程序不多,还不能深入体会用Vim或Emacs开发程序的乐趣。我只是觉得这很酷,你看,Linux之父Linus多年来用的是一款MicroEmacs,它比GNU Emacs或XEmacs少许多功能,但Linus就是用它在维护Linux。 微软的大牛Don Box,Com之父,一直用Emacs,他说谁也不能夺走他的编辑器。他还在网上放了一段他用Emacs写C#程序的视频。

编程大师们的选择,也是Emacs和Vim被追捧为神器的原因之一。

4. 神器引发的圣战

Vim用户和Emacs用户有着旗鼓相当的品位,应该互相欣赏才对。现实却是,忠诚于Vim的用户和忠诚于Emacs的用户互不相容,常常没完没了地打口水仗。Emacs用户说Vim的操作方式单一而古怪,Vim用户说Emacs体积庞大,启动缓慢。

很有点一山不容二虎的意思,大概因为二者都处于神器的高度,才会斗争不断吧。也可能是因为二者截然不同的设计哲学吸引的用户在价值观上也互不认同。

正因为两者难分高下,新人总是在Vim和Emacs之间犹豫不定,很难决定到底要皈依哪一个神。

参考文章

为何 Emacs 和 Vim 被称为两大神器

normal模式下

移动/编辑相关

快捷键 作用
h
j
k
l
ctrl + j/k 上下跳4行
ctrl + u/d 上下9行
i 在光标前插入
a 在光标后插入
A 到末尾插入
I 到首插入
s 删当前字符并进入插入模式
zc 折叠代码
zo 打开折叠
u 撤销上一次代码修改/undo
ctrl + r 与u相反/redo

tab/buffer/标签相关(按vim的用法来说应该叫buffer)

快捷键 作用
ctrl + h/l 左右切换tab
ctrl + w 关闭当前tab
<leader>bl 关闭右边所有tab
<leader>bh 关闭左边所有tab
<leader>bc 选择关闭tab

窗口相关

快捷键 作用
option + h/j/k/l 左下上右切换窗口
sv 左右分屏
sh 上下分屏
sc 关闭当前窗口
<leader> + t 底部打开terminal
<leader> + vt 侧边打开terminal
s, 当前窗口左右比例缩小
s. 当前窗口左右比例放大
sj 当前窗口上下比例放大
sk 当前窗口上下比例缩小

tree(侧边栏)相关

快捷键 作用
ctrl + m 隐藏与显示tree
Enter 打开tree中选中的文件
v 左右分屏打开
h 上下分屏
i 忽略node_modules
. 显示与隐藏隐藏文件
F5 refresh file
a create file
d remove file
r rename file
x cut file
c copy file
p paste file
s system_open file
o open file

telescope搜索相关

快捷键 作用
ctrl + p 搜索文件
ctrl + f 全局搜索
ctrl + j 向下移动选择文件
ctrl + k 向上移动选择文件
ctrl + n 历史搜索下一个
ctrl + p 历史搜索上一个
ctrl + c 关闭搜索页面
ctrl + u 预览上滚
ctrl + d 预览下滚

LSP相关

快捷键 作用
gd 跳到变量的定义处
gh 悬浮显示当前变量的信息
gp 显示当前文件的错误的代码信息
gj 跳到下一个错误代码的地方
gk 跳到上一个错误代码的地方
<leader> + f 格式化代码
ctrl + j/n 选择下一个提示
ctrl + k/p 选择上一个提示
Enter 确认选择
<leader> + rn 重命名变量名

退出

快捷键 作用
q :q
qq :q!
Q :qa!

Inser模式下

移动/编辑相关

快捷键 作用
option + h/j/k/l 左下上右移动
ctrl + b 到末尾
ctrl + e 到首
ctrl + j 开辟新行

Visual模式下

移动相关

快捷键 作用
j 向下移动代码
k 向上移动选中的代码
< 左缩进代码
右缩进代码
= 选中代码后格式化代码

常用命令

命令 作用
:q 退出
:q! 强制退出
:w 保存
:qa 退出并关闭
:qa! 强制退出并关闭
:wq 保存并退出
:PackerCompile 每次改变插件配置时,必须运行此命令或 PackerSync, 重新生成编译的加载文件
:PackerClean 清除所有不用的插件
:PackerInstall 清除,然后安装缺失的插件
:PackerUpdate 清除,然后更新并安装插件
:PackerSync(最常使用) 执行 PackerUpdate 后,再执行 PackerCompile
:h base-directories 查看详细文档
:echo stdpath("data") 查看你系统下Neovim的数据存储在标准数据目录的实际路径
:colorscheme Tab键 查看内置主题色
:echo $VIMRUNTIME 查看VIMRUNTIME 具体的路径
:h nvim-tree.setup 查看nvim-tree的帮助文档
:NvimTreeToggle 再按Enter即可打开或关闭侧边栏
:checkhealth telescope 检查telescope依赖情况
:Telescope find_files 打开搜索文件窗口,快速打开文件
:Telescope live_grep 可以打开搜索窗口,输入内容后,结果会实时显示
:Telescope buffers 命令可以列出打开的 buffers
:Telescope git_files 列出 git 文件
:Telescope man_pages 列出帮助
:Telescope env 打开环境变量列表
Telescope colorscheme 换肤功能
:TSInstallInfo 命令查看 language parsers 列表与安装状态
:TSInstall <language_to_install> 安装指定的 Language parser 例如:TSInstall javascript
:TSModuleInfo 查看你的模块是否开启成功
LSP相关命令
:h lsp 查看 LSP 文档
:LspInstallInfo 安装 LSP Servers的图形化界面
j/k 移动光标到你要安装的 server
i 安装server
X 卸载该 server
u 更新 server
U 更新所有 servers
c 检查 server 新版本
C 检查所有 servers 的新版本
Esc 关闭窗口
? 显示其他帮助信息
:LspInfo 查看绑定的 Language Server 信息
:NullLsInfo 查看源的激活情况
:lua vim.lsp.buf.formatting_sync() 格式化代码
:lua vim.lsp.buf.formatting_sync(nil, 9999) 不加参数可能会报Time out
echo executable('xxx') 查看某个命令是否可用 例如echo executable('rubocop')查看rubocop是否可用,一般用来排查格式化代码时需要的命令是否已安装

参考文章

Neovim 是一个现代的、快速的且与vim完全兼容的文本编辑器。它支持插件、LSP、GUI、web browsers 等等。各种各样的插件可以极大的提高Neovim的工作效率,随着使用时间的增加安装的插件也越来越多,所以有必要使用一个管理插件的插件来规范管理大量的插件,这样的插件称为插件管理器。Neovim 有各种各样的插件管理器,本文的目的就是列出这些常用的插件管理器,以方便读者选择。

  • lazy.nvim: lazy.nvim is a modern plugin manager for Neovim.
  • pckr.nvim: Spiritual successor of https://github.com/wbthomason/packer.nvim
  • packer.nvim: packer.nvim is currently unmaintained. For the time being (as of August, 2023), it is recommended to use one of the following plugin managers instead: lazy.nvim or pckr.nvim
  • paq-nvim: Paq is a Neovim package manager written in Lua.
  • neopm:Plugin manager for neovim, pre-alpha stage. Expect breaking changes.
  • dep: A versatile, declarative and correct neovim package manager in Lua. Originally written for personal use by luaneko.
  • optpack.nvim: This is a neovim plugin manager that uses only opt package.
  • pact.nvim: pact is a semver focused, pessimistic plugin manager for Neovim.
  • vim-plug:A minimalist Vim plugin manager.Just one file with no dependencies. Super easy to set up.
  • Vundle.vim:Vundle is short for Vim bundle and is a Vim plugin manager.
  • pathogen.vim:Manage your 'runtimepath' with ease. In practical terms, pathogen.vim makes it super easy to install plugins and runtime files in their own private directories.
  • dein.vim: Dein.vim is a dark powered Vim/Neovim plugin manager.
  • volt: Multi-platform CLI tool managing Vim plugin life

项目地址:https://github.com/echasnovski/mini.nvim

项目简介

Mini.nvim 是一个由开发者 echasnovski 创建的简洁高效的Neovim配置库。它旨在提供一个基础但全面的功能集,让你的Neovim体验既精简又高效。作为一个开源项目,Mini.nvim 已经吸引了众多用户和贡献者,并且持续更新以适应不断变化的开发需求。

技术分析

Neovim 基础

Neovim 是 Vim 的一个分支,具有更高的可扩展性和性能优化。Mini.nvim 利用了 Neovim 的这些优势,通过精心挑选的插件和配置,实现了极佳的交互性和速度。

Lua 配置

Mini.nvim 使用 Lua 语言进行配置,这是一种轻量级、快速且易于阅读的语言。Lua 的使用使得配置文件更易理解,降低了维护难度,同时也方便了对现有配置的个性化修改。

插件选择

该项目选用了诸如 nvim-lspconfig(用于语言服务器协议支持), telescope.nvim(用于查找和选择文件),和 treesitter(语法高亮和结构解析)等优秀插件,为开发环境提供了强大的功能,而不会牺牲性能。

敏捷性与性能

Mini.nvim 的设计注重启动速度和运行效率。它的核心理念是“只加载你需要的东西”,避免了不必要的资源消耗,确保在日常使用中流畅无阻。

应用场景

  • 开发环境: Mini.nvim 提供了一套完整的 LSP 支持,可以满足大多数编程语言的代码智能提示和自动完成。
  • 文本编辑: 对于日常文档编辑,其优秀的搜索、替换和导航工具使工作效率倍增。
  • 远程工作: 在低带宽或资源有限的环境中,Mini.nvim 的轻量化特性尤为突出。

特点

  1. 简洁 - 只包含必要的组件,避免了过度配置。
  2. 模块化 - 容易添加或移除特定功能,便于自定义。
  3. 高性能 - 专为速度和低内存占用优化。
  4. 可扩展 - 灵活地与新的插件和配置集成。
  5. 社区驱动 - 有活跃的开发社区支持,问题反馈和新特性更新迅速。

结语

无论是初识Neovim的新手,还是寻求简约高效的老手,Mini.nvim 都是一个值得尝试的选择。其优化的配置和强大的功能组合,能够提升你的编辑器体验,助你在编程旅程中更加得心应手。