atuinsh/atuin

[Bug]: history list command cannot deal with multiline command

gigberg opened this issue · 0 comments

What did you expect to happen?

1. bash中的跨行命令【多行字符】,

for multiline shell command:

cat xx.ini \
yy.ini

\n: 这是一个转义序列,用于编程语言(如 C、Python 和其他许多语言)中表示换行符。在字符串中,\n 代表一个换行字符。
^J: 这是一个控制字符的表示方法,通常在某些文本编辑器(如 vim 或 nano)或终端中用来表示换行符。当你在命令行中按下 Ctrl + V 然后 Ctrl + J 时,会输入一个换行符并显示为 ^J。

2. 在zsh的history命令和history文件中,直接使用字符\n表示为【单行字符】(这里用\n而非^J代表换行?)

image

3. 在atuin的sqlite数据库中直接原样保存为text类型的【多行字符】

its format in ~/.local/share/atuin/history.db

SELECT * FROM history
WHERE command LIKE '%' || X'0A' || '%' ;  #sqlite dont support CHAR(10) expression

image

4. 在atuin的各项命令中,包括atuin tui文字ui界面(也即atuin search -i),atuin search,atuin history list三种场景下都是,直接使用字符^J表示为【单行字符】(注意前面的反斜杠, 是原始bash多行语句中每行结尾自带的反斜杠)

atuin search -> ^J

image

atuin hisotry list -> ^J

image

5. 关于atuin history list【^J】和fzf的集成(根据输入输出端分别如何处理readline命令换行符【行内】和跨行语句换行符【行间】,有三种情况)

前提:fzf通过行间空白符来区分单条语句行(无论该语句内是否有行内换行符)
①输入history行间空白符=行内空白符=\n(或表示为^J),此时行内换行符被连带解析,导致所有跨行单命令被分解
history list | fzf,
image

②输入history行间空白符改为null,输出fzf仍使用\n来解析行,此时行内换行符被连带解析,行间换行符反倒没被解析,导致没有得到任何有效命令行
history list --print0 | fzf,fzf用^J来分隔行
image

③输入history行间空白符改为null,输出fzf相应地也使用null来区分语句行(无论是单行还是跨行命令【可以将换行控制字符转义\n [zsh history]或^J [atuin history]从而压缩成一行】都看成一个语句行),总之保持了跨行命令的完整性,未误将其识别为多条语句行。
history list --print0 | fzf --read0,fzf用\0,也即null来分隔行,其它字符比如^J都当成行内字符
image
image

参见Add --print0 to history list #1274

touch "file with space.txt"[换行符①]
touch "filewithnewline
[换行符②].txt"
touch "normalfile.txt"

注:find -print0和xargs -0解释及用法

默认情况下, find命令每输出一个文件名, 后面都会接着输出一个换行符① ('\n'), 因此find 的输出都是一行一行的【当然下面提到的两类跨行文件名则是,输出为相应的若干行,换行符② (假定是^J, 本质上字节码都是X'10', 两种因为受到的操作不同所以这里有意区分成两类来考虑)】

xargs 默认是以空白字符 (空格, TAB, 换行符) 来分割记录的, 因此文件名 ./file 1.log 被解释成了两个记录 ./file 和 1.log, 不幸的是 rm 找不到这两个文件.

为了解决此类问题, 让 find命令在打印出一个文件名之后接着输出一个 NULL 字符 ('\0') 而不是换行符, 然后再告诉 xargs 也用 NULL 字符来作为记录的分隔符(也即换行符①【或者说空白符①】都使用null,来同“空格文件名/跨行文件名”等中的换行符②【或者说空白符②】在形态上区别开来以便能正确识别每条单命令[也就是让跨行的也能识别成一条单命令]). 这就是 find 的 -print0 和 xargs 的 -0 的来历吧.
image

另:关于如何输入跨行单命令,①反斜杠+enter换行,②字符串内双引号+enter换行

image

What happened?

如上

Atuin doctor output

如上

Code of Conduct

  • I agree to follow this project's Code of Conduct