可能是elvish的问题,我用mintty也是会闪,表现为一些字符好像被鼠标选中然后取消选中了的样子,mintty是对标xterm的
同一个 Windows Terminal 版本,我用 HEAD 和 0.19.2 都没问题。建议检查 Windows Terminal 的渲染设置。
多谢提醒,开了下面这个设置后,基本不会闪了,只有命令从红色变成绿色的时候会闪一下,还有长按Backspace 删除字符的时候会有点闪。总的来说,不影响使用了。
这个问题估计是 elvish 在每个输入都重新绘制屏幕,检查用户输入的命令是否合法。
闪的问题应该是 Windows Terminal 的问题,Powershell 下在重新绘制屏幕时也是会闪的。
输入字符时在 Windows Terminal 会闪的问题,是 Terminal的原因,不是 Shell 的问题。
目前最新的 Windows Terminal Preview v1.18.1462 已经修复了。
Nushell 也有同样问题。
我用Window Terminal里面的 WSL Ubuntu 也出现了闪的情况。
换成预览版的 Windows Terminal, 一点都不闪
写了一个GNU TeXmacs的Elvish插件:
现在只能执行单行的命令
我觉得这种 map func data
并不友好,同样是函数式编程,在Scala里面可以:
data.map(func)
我觉得这样更友好。倒装的写法,其实并不那么易读
@xiaq 能否考虑让 Elvish 有更友好的函数式编程的写法,你是否赞同Scala这种写法更易读易写?
然后Scheme的语法,会导致末尾有很多)))))))
Elvish 里可以用 pipeline 写成
put .* | each {|f| print $f; du -sh $f}
这里的 |
在实现上是使用了IO吧?
比较喜欢类似这样的语法,(这是我参考Scala的语法写的)
(put .*).foreach { f =>
print $f
du -sh $f
}
然后,沿用Elvish的既有的语法的话,我个人希望是这样的:
(put .*):each { |f|
print $f
du -sh $f
}
希望有这样的设计:
[ 1 2 3 4 ] : each { |f|
echo $f
}
这里的 :
表示,each是可以作用在list上面的一个函数。
今天在公司Cat Talk这个环节,和同事探讨 Elvish
尝试写一个filter的实现:
fn filter {|pred l|
var res = []
for e $l {
if ($pred $e) {
set res = (conj $res $e)
}
}
put $res
}
# filter {|x| > $x 3} [1 2 3 4 5 6]
each {|x|
echo "rm -rf " $x
} (filter {|png_file|
if ?(test -f $png_file) { put $true } else { put $false }
} [(each {|x|
echo $x.elv
} [1 2 3 args each])])
感觉还是有一些罗嗦,我是指 []
, {}
, ()
这些符号的组合。我的实现应该有不少地方还是可以优化一下的
按照我在上面的设计,我比较期望的语法是这样的:
[1 2 3 args each] : each { |x|
put $x.png # append `.png` to each element
} : filter { |x|
os.exists $x # check if $E:PWD/$x exists
} : each { |x|
rm -rf $x # remove the png files
}
另外反馈一个新手入门的问题:
反馈一个最近学习 Elvish 的坑点: https://elv.sh/ref/language.html
如果只看 Language Specification的话,会发现,想在一个列表中append一个元素,在文档(语言的标准)里面没有提供,然后需要跳转到内置函数里面去寻找对应的内置函数,比如conj
。
https://elv.sh/ref/builtin.html
然后这个页面的排序方式就是按字母排序(alphabet),找相关函数还是比较费劲的
put [1 2 3 args] | each $fn
就可以了
不需要关注这种实现细节, 因为语言设计者不想给你其他选择。
最主要的是,用 put 和 | 已经可以完成的事,还要再加操作只会影响正交性。
@xiaq 倒是要催一下 disown 的实现,从 elvish 用 & 开一个 emacs 结果关闭终端会把 emacs 杀掉很麻烦
有的 @LdBeth 也提到了……
Re #92:|
用来传值用的是 Go channel,不通过文件 IO。|
的实现原则上可以完全抽象化,类似于 Clojure 的 seq。不过对于 Elvish 的应用场景来说,channel 带来的性能损失不重要。
Re #93:比较 idiomatic 的写法是 stream processing 就输出 stream of values,这样不需要用到 conj
:
fn filter {|pred @rest|
each {|x|
if ($pred $x) {
put $x
}
} $@rest
}
put 1 5 6 2 | filter {|x| > $x 3}
filter {|x| > $x 3} [1 5 6 2]
Re #94:这个似乎没比现在 pipeline 的写法要短多少?
Reference 里面的东西对学习确实不是很友好。暂时没时间写教程……
@aqua0210 命令变色的时候会闪是因为 Elvish 不缓存外部命令 lookup 的结果,然后 Windows 的 PATH
里面很容易有各种垃圾,然后 disk IO 也慢……把 PATH
清一下可能会快很多。
当然治本的办法还是引入缓存……
这个新的写法超赞!Elvish牛逼!
然后这个还是 Go Channel,从这个意义上,我觉得 Elvish 作为一门通用的脚本语言(类似于Lua),也是非常赞的。我有一位同事,他非常希望 Scala 能有 Goroutine,希望能有一门语言结合Go和Scala优点。
然后,我个人最近开始用 Elvish 之后,非常希望能实现一门类似于Lua的embedded script language,有一些内置的数据类型,然后语法尽可能和Scala保持一致。
把
PATH
清一下可能会快很多。
我写的Elvish脚本,第一句话就是:
set paths = [
/path/to/1
/path/to/2
]
能够低成本的得到一个干净的shell脚本执行环境,真的超赞!