Fish-shell: 缩写

创建于 2013-05-11  ·  92评论  ·  资料来源: fish-shell/fish-shell

引入缩写作为别名的替代,可能会取代它们。

缩写与别名完全一样,只是它们会在您在命令行中键入时扩展为完整形式。 假设您有gc作为git commit的缩写; 现在,如果您键入gc -am "did stuff" ,当您在 "gc" 之后键入空格时,命令行会发生变化,最终以git commit -am "did stuff" 。 这应该只发生在命令位置,当你输入一个空格或按回车键时。

_原文如下:_

用自扩展的短格式替换别名

我不知道该怎么称呼这些,但无论如何。 这个想法是,如果您输入“g”作为命令,则在您输入空格或回车时它会扩展为“git”。

论据:

  • 它解决了许多与完成有关的问题。 由于别名扩展为“实时”,因此 git 完成正常工作,并且commandline不必撒谎或进行任何其他类似的黑客攻击。
  • 这很容易实施。 我可以用bindcommandline来完成,尽管我没有尝试编写完整的实现。 我们不需要像其他提议的解决方案那样对functioncomplete等进行任何更改。
  • 它可以说是“可疑的”:用户可以看到展开的表单,它没有隐藏在别名中; 它是即时和实时的,类似于完成,使用prevd-or-backward-word等提示重新绘制。
  • 当复制粘贴命令行以供他人使用时,它不会充满他们不知道的自定义别名。
  • 如果几乎正确,您可以编辑展开的表单。

反对意见:

  • 没有解决alias git=hub的问题,这个问题目前不存在,但引入了一些别名完成建议,比如这个。 但是,您可以简单地编写一个普通函数function git; hub $argv; end来绕过这个提议的别名系统。
  • 有些人可能会觉得在您键入时更改命令行而不按 Tab 之类的任何内容会令人惊讶。
  • 您可以编辑扩展表单的原因也是您无法删除仅用两个退格键键入的内容的原因。 甚至 CTRL-W 也可能不够,因为例如您可能将gc扩展为git commit 。 如果它是唯一的命令,则 CTRL-U 会起作用,但如果您使用管道的别名,它会删除太多。 也许我们可以为“杀死当前命令而不是整个缓冲区”引入一个新的绑定。
  • :题:

现有技术:

  • :abbreviate在 Vim 中
  • 我想也许是 Chrome 中的搜索引擎?

讨论。

enhancement

最有用的评论

如果鱼在文件中保留缩写会很好......

来自手册页:“缩写使用通用变量存储。” 这意味着您可以在 var name fish_user_abbreviations下的 _~/.config/fish/fishd.macaddr_ 文件中找到它们。 abbr命令只是操作通用变量。

所有92条评论

另一个想法是像在 Vim 中一样命名这个“缩写”,然后在另一个问题中决定如何处理别名[我倾向于认为它们应该被删除]。

想到另一个反对的论点:

  • 不能在脚本中使用这些“别名”。 不确定在脚本中使用别名是不是一个好主意,但我们可以有一个扩展“缩写”的功能和/或我们可以将鱼的缩写挂钩到编辑器中,让它们也可以在那里扩展输入。

我喜欢你的提议,听起来很酷很可疑:+1:

我也喜欢这个。
这是对“别名完成”#393 问题的非常干净的解决方案,这很烦人。
当执行ll<tab>时,这与ll (Alias)打印输出相结合将是完美的。

由于alias只是今天function周围的脚本包装器,我也希望对其进行更改,以便函数和别名之间存在明显差异,因为在此之后它们在很多方面都不同,例如:

  • 句法
  • 表达能力
  • 用法

@gustafj我认为将这个想法称为“缩写”可能更好,并将alias替换functionabbreviate的有用错误消息的内容。 想法?

另一个注意事项:

我的意思是这只会影响命令行中的命令,因为如果g git在参数位置继续扩展到sudo (这意味着您可以将 sudo 与缩写一起使用 - 这是您不能使用别名做的!)以及某些明确完成的情况,例如至于 git 自己的别名,或者如果您键入长选项的一部分。 但是,正确执行此操作可能会很棘手,并且只会在完成过时的情况下妨碍您,并且如果您确实想要sudo g而不是sudo git您现在必须执行类似sudo (echo git) 。 也许我们可以说引用的参数永远不会扩展,所以你可以说sudo "g" 。 不确定这是否太神奇和令人惊讶,或者实际上正是人们所期望和直觉的。 想法? :-)

缩写对我来说听起来不错(但我是一个普通的 vim 用户,所以我可能有偏见......)。
当我想到它时,可以用它完成很多“有趣”的事情,但是(正如您已经指出的那样)在这个雷区中也隐藏着陷阱:/

我认为如果它是完全自动的并且在命令行中的任何地方,它可能会出现问题/烦人,主要是因为如果它扩展到你不想要的东西,特别是如果它扩展到一个长字符串,撤消缩写可能会很乏味。

我个人的一些想法:
它应该通过使用space还是应该通过tab或其他方式由选项触发?
它应该只用于简单的字符串 ex g for git吗?
它应该只适用于命令行上的第一项还是任何地方?
是否可以对当前日期Tue May 14 20:23:03 CEST 2013进行字符串 -> 值转换 ex d Tue May 14 20:23:03 CEST 2013
是否可以扩展子shell ex vim (find . -iname '*cfg')<tab>给出

foo.cfg bar/poo.cfg foo/bar/more/beer.cfg
> vim

对你的想法的想法!

它应该通过使用空格自动还是应该通过选项卡或其他方式由选项触发?

我认为这不适用于任何 _but_ 空格(并输入),因为重点是获得使用别名获得的无缝体验,您不必考虑某些东西是否为别名,而制表符不会工作要么是因为g<Tab>应该完成以g开头的命令。 如果我们添加一个新的绑定,比如 CTRL-X,我们现在有三种类型的完成:正常的、自动建议的和缩写的。 我真的认为这需要用空间来完成,或者根本不需要。

它应该只用于 git 的简单字符串 ex g 吗?

在命令位置,应该可以在缩写中包含参数。 例如gc扩展到git commit --all或者你有什么。 基本上我认为缩写与别名完全一样,除了它们在命令行上实时扩展。

它应该只适用于命令行上的第一项还是任何地方?

只有在指挥位置上才可能是一个好的开始。 然后我们可以_也许_试验我之前建议的参数位置用例。

是否可以在 2013 年 2 月 14 日星期二 20:23:03 CEST 的当前日期进行字符串 -> 值转换?

你的意思是在论证位置? echo d扩展以回显日期? 我真的认为如果我们完全使用参数位置缩写,则需要非常保守地使用它并且_only_当参数是命令(如sudo )或命令有自己的别名系统时(如git )并且扩展与不扩展具有完全相同的效果(因此我们只扩展可用性)。

是否可以扩展子shell ex vim (find . -iname '*cfg')<tab>

我认为这是一个关于完成而不是缩写的问题,因为我不认为缩写涉及制表符和在空间上扩展子外壳可能是一个坏主意。 但是不确定它是否可以用于完成,因为您已经可以完成变量名称而无需扩展它们。

不过它可能很有用。 就像我想象的那样rm *.png ,扩展通配符并从列表中删除一些文件。

怎么样:我们有一个类似于完成系统的通用“扩展”或“缩写”系统; 我们绑定 CTRL-X 或其他用于扩展令牌的东西; 在指挥位置,我们还会自动扩展缩写。 通过使这些扩展明确化,这也可以使sudogit用例的工作不那么突兀。

不过,这比我最初的想法要大得多。 :眨眼:

空间作为触发器对我来说听起来不错,可能会提供最佳的用户体验。
展开*.png听起来很有趣;)
我自己不喜欢为不同的东西使用很多不同的绑定,也许可以使用“双标签”来代替新的绑定。
例如....*.png<tab>给出press <tab> again to expand *.png (子shell 相同)。

但最好将此建议限制为:指挥位置的缩写,扩展使用空间。
并将“扩展子外壳/通配符”和 sudo 支持作为单独的一个?

不确定双选项卡是否会起作用,因为当前在完成之间循环。 Vim 似乎有 CTRL+] 用于扩展缩写而无需输入空格...

我认为如果我们真的进行实时扩展,那么缩写应该以某种方式实现,所以这些想法是相关的。 但是,如果我们不进行实时扩展,则仍应单独考虑缩写。 所以不确定在这里做什么。 :-)

是的,您对<tab>的权利只是考虑子外壳(目前它什么都不做)。
可以更改<anything><space><tab>的当前行为,该行为当前循环遍历当前目录中的所有可用文件(首先将它们全部打印出来)。
前任

> ls <tab>
a.cfg  b.cfg  c.cfg  d.cfg
> ls <tab>
> ls a.cfg<tab>
> ls b.cfg<tab>

但我宁愿使用新的组合键进行“实时扩展”,也不愿没有它;)
*.cfg扩展到a.cfg b.cfg c.cfg d.cfg感觉非常有用。
但是所有形式的可能扩展都应该是可扩展的,而不仅仅是通配符,前括号完成(我宁愿看到删除......但这是一个不同的问题#354)

但是所有形式的可能扩展都应该是可扩展的,而不仅仅是通配符,前括号完成(我宁愿看到删除......但这是一个不同的问题#354)

同意两个帐户。 我想知道双引号是否也应该可以扩展... echo "hello $USER" -> echo "hello dag"

我认为我们在这里谈论的实际上是“评估”而不是“扩展”,而另一方面缩写与评估无关,所以这些想法可能是分开的,我会为另一个提出一个新问题并进行编辑这一点。

这是一个基本的工作原型:

function __fish_expand_abbreviation
    if test (count (commandline -poc)) -eq 0
        switch (commandline -t)
            case g
                commandline -t git
            case gc
                commandline -t 'git commit'
        end
    end
end

bind \  '__fish_expand_abbreviation; commandline -i " "'
bind \n '__fish_expand_abbreviation; commandline -f execute'

我注意到的一个问题是,如果您按 Enter 键来执行缩写的命令行,则扩展形式会突出显示为错误(未知命令),甚至包括参数。

我非常喜欢这个,所以我实现了一种管理这些缩写的方法。

最后,我认为这些应该以相同的方式处理完成和函数。 使用它自己的缩写文件夹可以保存它。

这是当前的实现:

function __fish_expand_abbreviation
  if test (count (commandline -poc)) -eq 0
    set -l token (commandline -t)

    if abbreviations -q $token
      commandline -t (abbreviations $token)
    end
  end
end
function abbreviations --description 'List, show and query abbreviations'
  if test (count $argv) = 0
    printf '%s\n' $fish_abbreviations
    return
  end

  set -l abbreviation_index 0
  set -l expanded_abbreviation

  for i in $fish_abbreviations
    set abbreviation_index (math $abbreviation_index + 1)
    echo $i | read -l abbreviation command

    if test $abbreviation = $argv[-1]
      set expanded_abbreviation $command
      break
    end
  end

  if test -n "$expanded_abbreviation"
    switch $argv[1]
      case -q --query
        return 0
      case -e --erase
        set -e fish_abbreviations[$abbreviation_index]
      case '*'
        echo $expanded_abbreviation
      end
  else
    return 1
  end
end
function abbreviate --description 'Define a new abbreviation'
  if test (count $argv) -lt 2
    echo 'abbreviate: Takes two arguments. First abbreviation and then expanded command'
    return 1
  end

  echo $argv | read -l abbreviation command

  eval "function $abbreviation; $command \$argv; end"
  abbreviations -e $abbreviation

  set -U fish_abbreviations $fish_abbreviations "$argv"
  return 0
end

然后你做这样的事情:

abbreviate !    'sudo'
abbreviate tf   'tail -f'
abbreviate l    'ls -la'
abbreviate l.   'ls -d .*'
abbreviate g    'git'
abbreviate gs   'git status'

更新 1:添加删除缩写并将它们存储在通用变量中的功能。
更新 2:也为缩写创建函数

看看函数是如何工作的,我们可以介绍:

  • abbred
  • abbrsave

这基本上是克隆这些功能。

好的! 不过,我并不_十分_确信我们需要一个~/.config/fish/abbreviations目录和随附的abbr{ed,save} 。 与函数和完成不同,它们单独加载并不慢,它们只需要定义一行。 我认为它们更像是bind ,也许我们可以有一个fish_[user_]abbreviations函数,比如fish_user_key_bindings函数,它会在鱼第一次尝试扩展缩写时加载? ( [user_]保持一致性,但我不确定我们是否应该提供任何默认缩写?)

我能想到有多个文件作为缩写的唯一原因是,如果您对存在的每个 git 命令都说一个缩写,并且有些带有参数,那么您希望这些文件与其他文件分开。 但这不是延迟加载函数和完成的工作方式:它们是根据命令名称加载的,所以如果我们为缩写这样做,我们最终会为每个缩写生成一个文件,每个文件只包含一行代码!

另一个想法是做一些类似通用变量的事情,甚至可能通过实际使用通用变量(如set -U fish_abbreviations )。 也许主机本地缩写有一个用例? 没有把握。

你有一些优点,我倾向于fish_user_abbreviations方式。

另一种方法是使用类似的完成方式,将所有相关的缩写词放入一个文件中,但这可能更难映射。

我一开始打算使用set -U fish_abbreviations ,但我喜欢由 git 维护配置,所以更喜欢将它们设置在某个地方,比如配置。 但是使用通用变量的好处是您可以在没有任何麻烦的情况下即时添加完成,例如 ( abbred , abbrsave )。 只需做一个abbreviate

一种解决方案是让命令确保唯一添加缩写并覆盖现有缩写。 然后它将使用fish_user_abbreviations进行引导,用户可以根据需要将自定义变量添加到通用变量中。

我现在有这个:
set -q fish_abbreviations ; or fish_user_abbreviations

但是如果我继续维护文件,那将不起作用。

更新了我以前的函数以使用通用变量,并增加了擦除它们的可能性,并在添加新函数之前检查它们是否存在。

我正在考虑让它更具交互性,比如询问它是否应该替换当前的缩写。 但由于它也可能是脚本化的,我不想这样做。 我将研究交互模式的确定。

好吧,完成的事情是,即使它们是为单个命令加载的。 如果当前命令行进程是git则加载completions/git.fish 。 当您有单独的命令名称时,您必须制作单独的文件,例如参见[ef]grep补全,它们实际上位于从这三个补全文件中的每一个调用的函数中。

对于缩写,我看不出有任何方法可以从缩写中知道要加载哪个文件,除非文件名 _is_ 缩写。 然后你不能在一个文件中有多个缩写。 我想我们可以在开始或第一次尝试扩展缩写时加载所有缩写文件,但这与加载函数和完成的方式不同,如果你有很多缩写文件,可能会很慢。

新想法: abbreviate -U用于制作通用缩写,而abbreviate -g或仅abbreviate用于制作全球缩写? 如果我们这样做,也许我们也应该考虑为bind这样做......

另外我认为abbreviate应该覆盖任何现有的缩写,与bindfunctionset ......

都是有效积分。 我认为像所有其他函数一样覆盖是有意义的。

我也喜欢通用和全局的建议,它提供了选择如何处理缩写/绑定的灵活性。 我不完全确定如何实现它,我想也许这应该是一个内置的来提高性能?

是的,我只是在鱼脚本中对其进行原型设计以进行尝试。 可能不希望每次键入空格时都会触发缓慢的脚本。 :眨眼:

是的,仍然工作得很好。 我现在已经使用它大约 1 天了,无法想象没有它我还能活下去,哈哈:grin:

:脸红:

我注意到的另一个问题是,如果您在非空命令行上执行C-a并键入缩写,它不会在空格上扩展,因为您位于单词的中间。 所以说你做make install oops 需要 root C-a !现在你有![cursor]make install并且输入空格不会扩展!缩写。 我将尝试用commandline -C解决这个问题。

第三个问题可能是一个功能,它仅在您键入空格或在缩写后输入时才会扩展。 因此,例如,如果您键入一个空格,则不是C-a ! C-e 。 这可能是一个功能,因为它可以避免缩写扩展,但我认为这有点不靠谱,我们应该使用像命令一样从字面上运行命令行,有点像command命令但也会计用于外壳函数和内置函数。 或者一些特殊的语法,比如命令位置的\g被解释为g而不是扩展。 特殊语法也不是很可疑,但是我们在命令特殊情况之前已经有了空格,意思是“不要登录历史记录”,所以耸耸肩。

第四,这是一个晦涩的,如果你喜欢上一段所以你有一个未扩展的缩写后跟一个空格,那么做C-a和空格,缩写被扩展并插入一个额外的空格之后! 同样,可能需要使用commandline -C检查光标位置。

哦,我在之前的评论中提到的第一个问题,只有在未扩展的缩写是未知命令时才会发生。 因此, gc缩写扩展为git commit并且整个事情突出显示为错误,在按 Enter 键(没有空格)时,但gs缩写扩展为git status并正确突出显示,因为显然我安装了 ghostscript:

> which gs
/usr/bin/gs

我还想知道缩写是否应该在你点击空格之前突出显示为已知的“命令”......目前,如果我输入g它在输入空格之前是红色的,但如果我输入git它突出显示甚至在空格之前已知。

如果我们在 C++ 部分这样做,所有这些问题可能会得到更好的处理。

语法高亮问题的愚蠢解决方法:为每个缩写创建一个别名/函数。 :笑:

实际上,也许无论如何这都是一个好主意,嗯...意味着缩写将在脚本中起作用,在evaltype ... 不确定。

您的解决方法是我目前正在使用的,但我不确定这是否是它最终应该做的,或者它们是否应该用于evaltype 。 对我来说,它们应该只是一个输入的东西。 但我想让他们运行以获得对 say sudo 的简单支持可能不会有什么坏处。

所以我已经使用当前的实现有一段时间了,这些是到目前为止发现的这个解决方案的问题(它们与方法无关:+1:):

  1. 粘贴文本时,最后一个空格会插入到行首,例如echo this is a test粘贴时变为_echo this is atest ,其中_是一个空格。
  2. 当使用read内置时, enterspace上的绑定也适用于那里。 因此,例如,如果我想输入一些非命令来读取它会扩展。 我想在最终实现中这应该默认关闭并由read -s启用
  3. 它有点慢(~0.25-0.5 秒)

您可以解决 1. 通过粘贴C-y

对我来说C-y只粘贴在鱼内(从鱼里面切下来的东西)而不是我的系统剪贴板。 在终端或其他应用程序之间复制。

我认为缩写是一个非常酷的主意。

我想让人们尝试使用缩写来完善正确的行为应该是什么。 我检查了对 master 缩写的初始支持,如 92099c7af23d0cebf52f89de4f9d829825e53ac8 和 f9c2a77c67754324f3036ec79501c6131d19562b。

如何使用它的示例:

set -U fish_user_abbreviations 'gc=git checkout'
gc

gc 将在空间或返回时扩展为“git checkout”。

缩写是一个列表,所以要添加一个新的:

set fish_user_abbreviations $fish_user_abbreviations 'grh=git reset --hard'

缩写在“命令位置”中扩展(例如,在子 shell 中或作为 if 的参数),但不能作为参数。 缩写词也不会在脚本中扩展。

以下是一些未解决的问题供讨论:

  1. “缩写”又长又难拼——我们能找到更好的名字吗? 如果“别名”尚未用于其他用途,它会很好。 一种可能性是反转它,例如“扩展”。 fish_user_expansions对我来说听起来不错。
  2. 应该如何指定缩写? gc=git checkout语法是轻量级的,但在fish 中的其他任何地方都没有使用。
  3. 我们可能不想在 enter 上扩展,只在空间上扩展。 在 enter 时展开有一个缺点,即用户在承诺运行它之前看不到他们运行了什么命令。 如果我们只在空格上展开,那么用户可以输入缩写,然后是空格,然后是回车,这样看起来不会太累。 第二种可能是让第一个 enter 触发扩展,第二个 enter 实际执行它。

另一方面,如果所有缩写都是由用户指定的,那么用户意外运行某些东西的可能性很低,因此在 enter 时扩展可能没问题。

  1. 缩写的扩展形式只是文本替换,其本身不一定是有效命令。 例如,您可以创建一个导致引号或括号不匹配的缩写。 我认为这是一个潜在有用的功能,但这意味着 fish 无法对包含缩写的代码进行语法检查,这意味着我们可能永远无法在脚本中使用它们。
  2. 缩写扩展本身是否应该在替换之前进行子壳和变量扩展? 我认为是的,因为这将使它们非常灵活。 然后缩写可以运行任意鱼代码。
  3. 如果我点击空格,并且缩写扩展并且我改变了主意,也许我应该可以点击删除并取消扩展它。

希望在他们生活了一段时间后,我们会知道什么感觉是对的。

谢谢,我现在正在运行它,到目前为止它似乎工作得很好。

  1. 我们可以使用缩写abbr来缩写。 至于alias ,如果我们认为这样更好,也许可以用这种行为代替。 如果人们想在他们的脚本中使用别名,他们可以进行函数包装。 缩写在我看来正是人们通常使用别名的目的。
  2. 我认为有一些辅助函数来定义和删除缩写会很好。
    例如: abbr gc 'git checkout'abbr -e gc
    在我看来,通过变量进行这种操作有点麻烦。 此外,最好确保缩写是唯一的。 所以你只需要定义一个新的来更新它。
  3. 我更喜欢现在的行为,如果您必须按空格,我的许多缩写(例如gs表示git status就没有那么有用了。 但是,我可以用双输入来实际执行它,就像你提到的那样。
  4. 就我个人而言,我对不在脚本中使用它们感到满意。
  5. 是的,这会很酷。 想不出任何缩写可以在我的头顶上使用它。
  6. 这也是一个好主意,例如,如果我过早地为缩写按空格。 这也可以与数字 3 建议作为双输入很好地结合在一起(但仍然不确定我是否想要额外的输入)。

无论如何, alias是 POSIX 兼容性包装器。 我对它做缩写没有任何问题。 如果你写abbr gc 'git checkout'或类似的东西,你无论如何都希望git checkout

过去几周我使用了 terlar 的脚本实现,今天切换到新的原生版本,所以这是我在开放点上的两分钱

  1. 我认为现在让alias做缩写是个好主意。 作为奖励,它将修复当前别名的不工作完成。
  2. terlar 说的好听
  3. 如果我需要在缩写上双击回车来执行它们,那真的会让我感到烦恼。 如果它们也像别名一样未扩展地工作,只需按一下 Enter 就可以了,但是我的历史记录中有未扩展的缩写
  4. ——
  5. 变量扩展是否意味着变量的内容将被放入命令中并因此放入您的历史记录中? 这将使历史方式中此类命令的可重用性降低,因为它们不再包含变量,而只包含其早期内容。 还是我误解了这一点?
  6. 我不认为自己使用 unexpand 功能,因为我使用的abbreviation不会超过 3 个字符,这意味着它们基本上都在肌肉记忆中,清除当前行会更快。 现在看到本机实现可以在任何地方使用,而不仅仅是在行的开头,这可能会有所不同。 但如果这并不意味着我必须总是按空格或双击 Enter 来展开它们,这可能是一个好主意。

“缩写”又长又难拼——我们能找到更好的名字吗? 如果“别名”尚未用于其他用途,它会很好。 一种可能性是反转它,例如“扩展”。 fish_user_expansions 对我来说听起来不错。

同意,但不以“扩展”出售。

应该如何指定缩写? gc=git checkout 语法是轻量级的,但在fish 中的其他任何地方都没有使用。

它应该只是一个新的内置函数,就像completebind或就此而言,用户可以调用但其底层存储是不透明的function

我们可能不想在 enter 上扩展,只在空间上扩展。 在 enter 时展开有一个缺点,即用户在承诺运行它之前看不到他们运行了什么命令。 如果我们只在空格上展开,那么用户可以输入缩写,然后是空格,然后是回车,这样看起来不会太累。 第二种可能是让第一个 enter 触发扩展,第二个 enter 实际执行它。

我真的认为我们想扩展Enter 。 我想我会得到很多令人沮丧的fish: Unknown command “gc”并且我不认为我会独自一人。 然而,扩展应该在命令行上发生,在它被执行之前,这样你会在回滚中看到扩展,并且它是在历史记录中结束的扩展形式。

缩写扩展本身是否应该在替换之前进行子壳和变量扩展? 我认为是的,因为这将使它们非常灵活。 然后缩写可以运行任意鱼代码。

我认为不应该。 通常最好在执行命令行时扩展它们。 假设我有一个用于创建时间戳记的缩写。 我输入缩写和一个空格,它会扩展为vim 12:34:56.txt 。 现在,我有几秒钟不运行此命令,时间戳将是错误的。 如果缩写扩展为vim (time +%T).txt会更好。 这做正确的事情,也意味着我可以选择在执行之前编辑命令行,例如使用不同的时间格式。 它还使其具有可重复性; 例如kill %firefox可以从历史记录中调用并重新运行,即使 PID 已更改。 最后,我认为它与其余的鱼更一致,其中命令行上的标记仅在执行时进行评估。

另一方面,在扩展时评估更强大,因为我们可以选择退出它,例如转义,但没有它我们不能真正_选择加入_。 我认为这可以通过 #751 更好地解决,因为它让用户控制评估。 尽管如此,这仍然没有提供一种方法来获得 _exact_ 缩写扩展的时刻; 这将是用户扩展个人令牌的时刻。 尽管如此,我确实认为它会更有用和更一致,因为它不仅适用于缩写,而且适用于命令行上可以评估的任何标记,但它已添加到命令行中。

如果我点击空格,并且缩写扩展并且我改变了主意,也许我应该可以点击删除并取消扩展它。

我认为这不应该是删除或退格,因为我使用缩写的部分动机是能够在执行前对扩展的 _parts_ 进行后期编辑。 也许更好的主意是为commandline -p定义的“从光标向后删除到当前进程”添加一个绑定。 这将解决缩写的问题(因为它们只在命令位置扩展),但同时在没有缩写的情况下非常有用。 这基本上像Ctrl-U一样工作,但在当前“进程”的开始处停止。 可以添加与Ctrl-K对应的变体,它在当前进程的 _end_ 处停止,以保持一致性,并且可能也很有用。

现在看到本机实现可以在任何地方使用,而不仅仅是在行的开头,这可能会有所不同。

我还没有尝试过@terlar的实现,但它是基于我的,其中扩展实际上在 _any_ 命令位置正常工作,而不仅仅是行首,荣誉commandline -p 。 实际上,我对我粗略的概念验证代码的工作能力感到敬畏! :鱼::心:

嗯,我想我从来没有真正尝试过在其他命令位置使用缩写。
是的,原型工作得很好,只是我提到的粘贴问题给我带来了不便,但不使用它的功能很好。

如果您使用Ctrl-Y , @sch1zo Pasting应该可以工作。

可能是这种情况,但大多数时候我通过选择/中键单击复制/粘贴,并且存在问题。 但是本机实现不再有这个问题,我已经更新了我所有的机器来使用那个。

因此,在使用本地缩写约 10 天后,我发现了一件让我烦恼的事情。 如果您已经输入了一个命令,然后跳转到该行的开头以在它前面加上一个缩写,则它不会展开,也不会在未展开的状态下工作。 对我来说常见的情况如下:
我的缩写之一是!=sudo所以现在当我想像vim /path/to/some/file/I/am/not/allowed/to/write那样编辑一些系统配置文件时,我经常很晚才意识到我需要 sudo,所以我通常只是跳到开头并加上!不幸的是, command not found消息。
我目前的解决方法是只为缩写添加一个别名,但因为如果它能够正确扩展会更好。

同意; 我们需要在输入空格时查看光标位置,而不仅仅是“第一个标记”。 或者,先插入空格,然后重新解析命令行并展开缩写。

提交 b6f495d1077b7627ea851da33936c77b2d594bb2 应该解决@sch1zo发现的问题(sudo 用 !)

另一件事要添加到此:我们可能应该默认情况下创建llla等别名而不是函数。

我将其重新定位为next-minor因为此功能可能会随下一个版本一起提供。

下一个版本可能很快,即下周末。 我现在只是在清理文档。

缩写将包含在其当前的、不完整的状态中。 在我们有了abbrev命令(或重新调整alias用途)之前,我不想公开或记录它们。 出于这个原因,我将其推回下一个专业。

我不认为alias是一个好词。 对我来说, alias是一个替代名称......不是要扩展的东西。

出于同样的原因,我也不喜欢abbr

我想过expand foo "foobar" ...但似乎expand命令已经存在:/太糟糕了,我认为expand将是最好的术语。

如何统一别名和缩写? 与其引入新功能或弃用alias ,不如引入一个配置选项来“扩展别名”。 这里的缺点是我们不喜欢 fish 中的配置选项(但我们可能会跳过配置选项)并且(也许是一件好事)这意味着我们不能混合这两种行为,尽管您仍然可以编写正常的函数来获得旧的别名行为......好处是我们没有两种方法可以做类似的事情,这很容易解释(“别名在鱼中扩展”)并且缩写实际上可以在脚本中使用(因为它们也是别名)这也意味着它们也不必在语法高亮中进行特殊处理。 通过将别名机制移到 C++ 代码中,我们可以避免当前别名实现的缓慢。 尽管如此,仍然需要弄清楚如何使补全对未扩展的别名起作用。

一项功能请求...

我以前使用函数在单个命令中发出常用命令组合,例如在一个操作中执行 git add、git commit 和 git push。

我喜欢新的缩写功能。 我认为它很大,并且正在尝试切换到它。 我对它仅限于单个命令扩展的事实感到满意。 但是,我仍然想一口气发出多个命令。 现在我可以只使用第一个命令的缩写,然后是分号,然后是第二个命令的缩写,等等。它工作正常,事实上我认为这样更好。

我的要求是扩展不仅可以由空格或输入触发,还可以由分号触发。 由于分号基本上等同于延迟输入,我猜这对你们所有人也有意义。

迫不及待地等待此功能在正式版本中发布!

我感觉合理。

1a7b33e8fb75dd702730ca9637d760fbd23a4000 扩展了分号上的缩写。

谢谢!

fish_user_abbreviations 存储在哪里? 我想将它们添加到我的 dotfiles 存储库中。

它目前是一个通用变量,所以它存储在 ~/.config/fish/config.fish 中。 但这只是暂时的破解,直到我们找到存储它们的正确方法。 欢迎在此反馈。

如果你愿意,你可以在 config.fish 中添加一行,如set -g fish_user_abbreviations...来手动设置它。

嗯,我在那里看不到那个变量。

我使用了set -U fish_user_abbreviations 'g=git' 。 这是将其放入 config.fish 的正确方法吗?

抱歉,我的意思是它将存储在~/.config/fish/fishd.[mac_address] 。 显然同步将不起作用(按设计),因为它已关闭 MAC。

要将它放在 config.fish 中,您可以编写 `set -g fish_user_abbreviations 'g=git'。 -g 代表全局,因为你每次都设置它。

我认为通用变量相当简洁,它只需要一个更好的 UI 围绕它。

如果我们将其用作数组,要么使用=来拆分键和值,要么使用 ASCII FS( \x1c ),然后使用 fish 函数来管理它( abbr )+ /- 一个网页界面页面会很有用。

必须考虑为出口/转让生产适当的产出。

@ridiculousfish啊,谢谢,这很有帮助! 我会暂时这样做,直到有一个导出过程。

顺便说一句,我对 A)包含所有缩写的单个文件或 B)每个缩写都有一个单独的文件持中立态度。 也许倾向于A,但不强烈。

我在现有实现周围添加了一个基本的 UI,如abbr - 使用abbr -h来查看更多。 我还在 Web 界面中添加了一个仅限查看的 UI,但最好能做得更多。

我们可以只使用每个数组项的第一个标记(空格分隔?),而不是使用=作为分隔符 - 这将简化实现。

通用变量是整洁的,但如果我们不直接暴露它,最好将它移动到__fish_user_abbreviations (并且可能会警告在本地或全局级别设置它)。

我更喜欢space-separated而不是使用=作为分隔符。 特别是因为该样式未在fish内的其他任何地方使用。

我同意这应该以空格分隔。 它更有意义,这意味着如果需要, =实际上可以成为缩写的一部分。 可能应该修改abbr命令以删除--add标志,而只使用两个参数。

关于$__fish_user_abbreviations ,我可以同情这个建议,但用户可能希望自己修改$fish_user_abbreviations而不使用abbr命令是合理的,我宁愿不鼓励任何人都可以直接修改$__fish_*变量。 同样,在本地或全局级别设置它是完全合法的; 不是每个人都想对这样的东西使用通用变量。

在相关说明中, read应该在使用--shell标志时扩展交互式输入的缩写。

我对鼓励在abbr命令之外修改变量的担忧是,扩展命令以支持作用域会增加其在 UI 方面的复杂性,但不这样做会导致潜在的误导结果。 目前没有合并变量范围,这可能会令人困惑 - 如果您设置通用扩展和(不同的)全局扩展,它们都应该工作吗? 那么,你如何在全球范围内取消普遍扩张? 这是人们愿意做的事情吗?

空间分离听起来是个好主意。 为了避免混淆,添加一个新的缩写可能需要无限数量的参数,第一个成为“词”,其余的连接在一起成为“短语”。

没有必要做任何工作来“支持范围界定”。 如果abbr仅使用$fish_user_abbreviations ,它将使用全局变量(如果存在),否则将使用通用变量。 这正是阅读器的工作方式。 唯一的问题是如果用户将$fish_user_abbreviations为顶层的局部变量,读者实际上也会看到这一点。 简单的解决方法是将-S标志添加到abbr函数声明中,这将让它看到在其父级中定义的局部变量。 但是绝对没有必要尝试合并缩写(也没有任何方法可以这样做,除非暂时删除其他范围内的变量)。

在实现这一点之后,我想我希望在扩展之前看到缩略语加下划线或以不同的方式突出显示。 这让我有信心正确地输入它们。 想法?

空格分隔符支持在 fbade198b942a666d3fc1110804a7da2c47918f1

如果你点击空格并且它没有扩展,那么你知道你没有正确输入它。 我不反对下划线或突出显示(让用户知道他们的命令行刚刚改变的原因当然是一个额外的提示),但我不确定我是否理解为什么你需要在点击空格之前有信心。

@ridiculousfish关于 fbade198b942a666d3fc1110804a7da2c47918f1,缩写足够新(并且在最近的大师之前没有记录),我们应该删除=支持。

我正在考虑返回前的情况,而不是前空间的情况

听起来不错。 我认为 _is_ 可能会过分强调突出显示,从而导致缓慢和迷失方向的信息超载,但我认为情况并非如此。 此外,我认为它会使用一些$fish_color_abbr-or-whatever变量,因此无论出于何种原因,那些愿意的人都可以轻松禁用它。

起初我想说我发现缩写与普通命令的突出显示行为不同是不直观的,直到我意识到我是不正确的并且它是一致的。

我的困惑来自于我混淆了突出显示和建议完成功能的事实。

例如,当我输入“echo”时,高亮显示为红色,直到我输入完整的命令,这是应该的。 然而,建议的完成成功地预测了我将要输入的内容,并让我确信我正朝着预期的方向前进。

我没有收到这样的缩写反馈,这很不幸,因为我不能经常想出令人难忘的命令缩写,尤其是那些扩展到复杂命令的命令。

事实上,我的目标是将范围广泛的命令打包到一个小的命名空间中(我拍摄了大约 5 个字符的缩写,并且有数百个)。 正因为如此,我更加依赖于我正在输入有效命令的 shell 指导。 完成建议完成所占据的角色的东西,但对于缩写而不是常规命令,真的会很有帮助,甚至对我来说也比标准命令更有帮助。

我可以看到缩写所带来的建议完成的难度。 将缩写扩展为实际命令是不直观的,因为它不再与您正在键入的内容相邻。 不过,我觉得它可能会比现在更好。

至少对我来说,在建议的补全中包括缩写本身(不是扩展)会让我感到痒痒。 我只是想看看我是否正确输入了已定义缩写的前缀。 这足以告诉我,我打字没有白费,因为我记错或打错了缩写。

我试图扩展abbr.fish来处理空格和=分隔符,但是我在不使用外部工具的情况下提出一个强大的解决方案并没有取得很大的成功。

我以为计划是删除 = 支持? 我正在考虑这样做,然后使用脚本将消息发布到 fish 邮件列表,该脚本将 $fish_user_abbreviations 写入人们可以运行以切换到空格的脚本。

嘿伙计,

在使用了很长一段时间的缩写之后,我想做一个笔记。

我是一个超级粉丝,他们让我的生活更轻松。 我特别喜欢这样一个事实,即其他人可以以熟悉的形式看到我发出的命令。

我唯一不喜欢的是没有缩写的历史。 由于我几乎对每个命令都使用缩写,这导致我在很大程度上失去了历史记录功能。 虽然您可能认为缩写应该足够短,不需要历史记录功能,但我发现自己错过了很多。 我定义了 200 多个缩写,其中一些仅略有不同。 例如,让历史向我展示我昨天发布的那个,对于涉及更多和不常使用的缩写非常有用。 由于我实际上使用缩写,因此我不得不在需要历史支持的地方使用函数,因为否则我真的没有历史。

再次感谢您的功能。

@binaryphile非常有趣。 听起来您对它应该是什么样子(即 UI)有一个想法。 你想更详细地描述它吗?

好问题。 我想我只是喜欢它,如果触发了任何扩展,那么缩写就会进入历史列表。 因此,如果我的缩写是“git clone”的“gclon”,那么当我点击空格(或分号)时,“gclon”将被添加到我的历史记录中。 我不会改变在历史记录中存储扩展命令的正常行为,因此两者都可用。

之后,当我开始输入缩写的前缀(例如“gcl”)时,我希望“gclon”是自动完成弹出的第一个选项。

理想情况下,那时我可以按 alt-f 并让它自动完成到扩展版本,并进一步提供从历史记录中扩展命令的新自动完成。 我想要那个,因为我可能在扩展后输入了更多参数,并且希望通过我最初输入它的相同路径(缩写然后是参数)以尽可能少的击键方式提供该参数。 由于历史记录中的缩写没有参数,alt-f 将是我按参数进一步完成完成参数的最自然方法。

我认为 ctrl-f 不会改变,只会前进到缩写的末尾,而不是扩展版本,因为没有关于您要扩展到什么的视觉提示。

我刚刚每晚建立并运行以最终测试这个! 我真的很喜欢这个功能,并且喜欢它附带的abbr命令。

我的反馈是我们需要一个很好的方式来导出 dotfile 备份。 我认为这些都应该以abbr --show输出格式放入一个文件中。 abbr --show现在对我来说已经足够了,我现在只是将它们通过管道传输到一个点文件中。 但我确实想要一种简单的方法在那个时候再次导入它们。 因此,如果 Fish 现在可以导入该格式,那将是一个很好的下一步。

按照帮助中的命令添加新缩写失败并出现此错误。

selection_235

目前您需要输入abbr -a "gco git checkout"但我认为支持手册中描述的情况更有意义。

啊,谢谢!

48d3536 进行了更改。

我认为我们应该在下一个次要版本中保留 '=' 分隔符支持并在此之后禁用它,或者(悄悄地?)升级人们的fish_user_abbreviations

我将按固定方式关闭它; 我提交了 #2051 来跟踪迁移。 非常感谢@dag的概念和所有测试它的人 - 期待很快看到这个发布!

W00t,谢谢大家,我真的很喜欢这个功能!!

我喜欢缩写,这是比别名更友好的体验。 非常感谢!

我在查找如何在 dotfiles 12 中存储缩写时遇到了这个线程。
如果有人出于同样的原因在这里绊倒,您可以使用abbr -s/--show 。 例如

abbr --show >> ~/.config/fish/config.fish

@dideler我正在使用类似于自动备份的东西,我还建议管道到sort

abbr --show | sort > fish_abbreviation_backup;

我将所有内容都放入一个 fish_abbreviation_backup 文件中,然后将其添加到 Homeshick 中进行备份。 不过,这一切都是自动化的,并在 cron 上运行。 备份 I source fish_abbreviation_backup ,fish 在执行abbr --show时显示字母顺序。

如果 fish 将缩写保留在文件中会很好,类似于它如何处理函数。

更新:存储时对缩写进行排序的问题-> https://github.com/fish-shell/fish-shell/issues/2156

如果鱼在文件中保留缩写会很好......

来自手册页:“缩写使用通用变量存储。” 这意味着您可以在 var name fish_user_abbreviations下的 _~/.config/fish/fishd.macaddr_ 文件中找到它们。 abbr命令只是操作通用变量。

谢谢,是否可以考虑将它们保存在 ~/.config/fish/abbreviations.fish 中以便我们可以轻松地将它们添加到我们的点文件中?

@ElijahLynn :我所做的是在 ~/.config/fish/conf.d/ 中有一个名为“abbrs.fish”的文件,其内容如下:

if not set -q fish_initialized
    abbr -a alsamixer alsamixer -c0
    abbr -a e emacs -nw
    abbr -a \$PAGER less
    abbr -a mu4e emacs --eval "\(mu4e\)"
    abbr -a pm pulsemixer
    abbr -a rm rm -I
    abbr -a sc systemctl
    abbr -a upo upower -i /org/freedesktop/UPower/devices/battery_BAT0
    abbr -a usc systemctl --user
    # Double-escaping needed
    abbr -a d2 env WINEPREFIX=/home/alfa/.wine32/ wine ~/.wine/drive_c/Program\\ Files\\ \\(x86\\)/Diablo\\ II/Diablo\\ II.exe
    abbr -a c curl -LO -C -
    set -U  fish_user_paths ~alfa/.local/bin $GOPATH/bin
    set -U fish_initialized
end

我在我的 dotfiles 中有这个,我可以把它放到任何我还没有用过的机器上,如果我想重置 abbrs,我可以将它们全部删除(我这样做set -e fish_user_abbreviations; set -e fish_initialized )和重启鱼。

谢谢,我可能遗漏了这个,但看起来您需要手动维护它,并且不能使用abbr命令轻松添加管理它们。

你在那里添加 abbr 命令。 这甚至可以是abbr --show调用的输出。

只有在指挥位置上才可能是一个好的开始。 然后我们也许可以试验我之前建议的论点位置用例。

我认为不仅开始的位置会很少,例如: s sudo s sudonnano可以从s n扩展sudo nano ,但不在当前实现中。

此页面是否有帮助?
0 / 5 - 0 等级