New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abbreviations #731

Closed
dag opened this Issue May 11, 2013 · 91 comments

Comments

Projects
None yet
@dag
Contributor

dag commented May 11, 2013

Introduce abbreviations as an alternative to aliases, possibly replacing them.

Abbreviations are exactly like aliases, except they're expanded into their full form live as you type them on the commandline. Say you have gc as an abbreviation for git commit; now if you type gc -am "did stuff" the commandline changes when you type the space after "gc" and finally ends up as git commit -am "did stuff". This should only happen in command position, and when you type a space or hit enter.

Original text follows:

Replace aliasing with self-expanding short forms

I don't know what to call these but anyway. The idea is that if you type "g" as a command it expands to "git" when you type a space or enter.

Arguments for:

  • It solves many of the issues with completions. Since the alias expands "live", the git completions work as normal and commandline doesn't have to lie or do any other hacks like that.
  • It's easy to implement. I can kinda do it with bind and commandline although I didn't try to write a complete implementation. We don't need any changes to function or complete etc, as in other proposed solutions.
  • It's arguably "fishy": the user can see the expanded form, it's not hidden in an alias; it's instant and live, similar to completions, prompt repainting with prevd-or-backward-word etc.
  • When copy-pasting a command-line for instructions to others, it won't be full of your custom aliases that they have no knowledge of.
  • You can edit the expanded form if it's only almost-right.

Arguments against:

  • Doesn't solve the problem with alias git=hub, a problem that doesn't currently exist but is introduced with some alias completion proposals such as this one. However you can simply write a normal function function git; hub $argv; end instead to side-step this proposed alias system.
  • Some might find it surprising to have the command-line change as you type, without pressing anything like Tab or such.
  • The reason you can edit the expanded form is also the reason you can't delete what you typed with simply two backspaces. Even CTRL-W might not be enough as you might have gc expand to git commit for example. CTRL-U will do if it's the only command but it will delete too much if you're using the alias for a pipe for example. Perhaps we could introduce a new binding for "kill current command but not whole buffer".

Prior art:

  • :abbreviate in Vim
  • I think maybe search engines in Chrome?

Discuss.

@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag May 11, 2013

Contributor

Another idea is to name this "abbreviations" like in Vim, and then decide what to do with aliases in another issue [I tend to think they should be removed].

Thought of another argument against:

  • Can't use these "aliases" in scripts. Not sure it's a good idea to use aliases in scripts anyway, but we could have a function for expanding "abbreviations" and/or we could hook fish's abbreviations into editors to have them expand on input there as well.
Contributor

dag commented May 11, 2013

Another idea is to name this "abbreviations" like in Vim, and then decide what to do with aliases in another issue [I tend to think they should be removed].

Thought of another argument against:

  • Can't use these "aliases" in scripts. Not sure it's a good idea to use aliases in scripts anyway, but we could have a function for expanding "abbreviations" and/or we could hook fish's abbreviations into editors to have them expand on input there as well.
@terlar

This comment has been minimized.

Show comment
Hide comment
@terlar

terlar May 11, 2013

Contributor

I like your proposal, sounds cool and fishy 👍

Contributor

terlar commented May 11, 2013

I like your proposal, sounds cool and fishy 👍

@gustafj

This comment has been minimized.

Show comment
Hide comment
@gustafj

gustafj May 12, 2013

Contributor

I also like this.
It's a very clean solution to the "completions for aliases" #393 problem which is quite annoying.
This combined with a ll (Alias) printout when doing a ll<tab> would be perfect.

As alias is just a script wrapper around function today, I would want that changed as well so that there is a distinct difference between functions and aliases since they differs in so many ways after this, ex:

  • Syntax
  • Expressibility
  • Usage
Contributor

gustafj commented May 12, 2013

I also like this.
It's a very clean solution to the "completions for aliases" #393 problem which is quite annoying.
This combined with a ll (Alias) printout when doing a ll<tab> would be perfect.

As alias is just a script wrapper around function today, I would want that changed as well so that there is a distinct difference between functions and aliases since they differs in so many ways after this, ex:

  • Syntax
  • Expressibility
  • Usage
@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag May 12, 2013

Contributor

@gustafj I think it's probably better to call this idea "abbreviations" and replace alias with something that shows a helpful error message pointing at function and abbreviate. Thoughts?

Contributor

dag commented May 12, 2013

@gustafj I think it's probably better to call this idea "abbreviations" and replace alias with something that shows a helpful error message pointing at function and abbreviate. Thoughts?

@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag May 14, 2013

Contributor

Another note:

I meant for this to only affect the command in a commandline, because it would be really annoying if g kept expanding to git in argument position. However, we might want some expansion in argument positions as well, for example with sudo (which would mean you could use sudo with abbreviations - something you can't do with aliases!) and certain cases of unambiguous completions such as for git's own aliases or if you type part of a long option. Getting this right might be tricky though, and would only get in the way if the completions are out of date, and if you actually wanted to sudo g not sudo git you now have to do something like sudo (echo git). Perhaps we could say that quoted arguments never expand, so you could then say sudo "g". Not sure whether that would be too magical and surprising or in fact exactly what one would expect and intuit. Thoughts? :-)

Contributor

dag commented May 14, 2013

Another note:

I meant for this to only affect the command in a commandline, because it would be really annoying if g kept expanding to git in argument position. However, we might want some expansion in argument positions as well, for example with sudo (which would mean you could use sudo with abbreviations - something you can't do with aliases!) and certain cases of unambiguous completions such as for git's own aliases or if you type part of a long option. Getting this right might be tricky though, and would only get in the way if the completions are out of date, and if you actually wanted to sudo g not sudo git you now have to do something like sudo (echo git). Perhaps we could say that quoted arguments never expand, so you could then say sudo "g". Not sure whether that would be too magical and surprising or in fact exactly what one would expect and intuit. Thoughts? :-)

@gustafj

This comment has been minimized.

Show comment
Hide comment
@gustafj

gustafj May 14, 2013

Contributor

Abbreviations sounds good to me (but I'm a regular vim user, so I might be biased ...).
When I think about it there are quite many "interesting" things that can be done with this, but (as you already point out) there are traps hidden in this minefield as well :/

I think it might be problematic/annoying if it is completely automatic and in any place in the commandline, mostly since undoing the abbreviation could be tedious if it expands to something you don't want and particularly if it expands to a long string.

A few thoughts of my own:
Should it be automatic by using space or should it be triggered by an option via tab, or something else?
Should it only be for simple strings ex g for git?
Should it only be applicable for the first item on the commandline, or anywhere?
Should it be possible to do string -> value conversions ex d for current date Tue May 14 20:23:03 CEST 2013?
Should it be possible to expand subshells ex vim (find . -iname '*cfg')<tab> gives

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

gustafj commented May 14, 2013

Abbreviations sounds good to me (but I'm a regular vim user, so I might be biased ...).
When I think about it there are quite many "interesting" things that can be done with this, but (as you already point out) there are traps hidden in this minefield as well :/

I think it might be problematic/annoying if it is completely automatic and in any place in the commandline, mostly since undoing the abbreviation could be tedious if it expands to something you don't want and particularly if it expands to a long string.

A few thoughts of my own:
Should it be automatic by using space or should it be triggered by an option via tab, or something else?
Should it only be for simple strings ex g for git?
Should it only be applicable for the first item on the commandline, or anywhere?
Should it be possible to do string -> value conversions ex d for current date Tue May 14 20:23:03 CEST 2013?
Should it be possible to expand subshells ex vim (find . -iname '*cfg')<tab> gives

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

This comment has been minimized.

Show comment
Hide comment
@dag

dag May 14, 2013

Contributor

Thoughts on your thoughts!

Should it be automatic by using space or should it be triggered by an option via tab, or something else?

I don't think this works with anything but space (and enter) because the whole point is to get the seamless experience you get with aliases where you don't have to think about something being an alias or not, and tab doesn't work either because g<Tab> should complete commands that begin with a g. If we add a new binding say CTRL-X we now have three types of completions: normal ones, autosuggestions and abbreviations. I really think this needs to be done with space or not at all.

Should it only be for simple strings ex g for git?

In command position it should be possible to include arguments in an abbreviation. For example gc expanding to git commit --all or what have you. Basically I think of abbreviations as being exactly like aliases, except they expand live on the command line.

Should it only be applicable for the first item on the commandline, or anywhere?

Only in command position is probably a good start. Then we can maybe experiment with the argument position use cases I suggested before.

Should it be possible to do string -> value conversions ex d for current date Tue May 14 20:23:03 CEST 2013?

You mean in argument position? echo d expanding to echo the date? I really think if we do argument position abbreviations at all, it needs to be used very conservatively and only when either the argument is a command (as in the case of sudo) or when the command has its own alias system (as in the case of git) and expanding would have the exact same effect as not expanding (so we only expand for usability).

Should it be possible to expand subshells ex vim (find . -iname '*cfg')<tab>

I think that's a question for completions and not abbreviations, as I don't think of abbreviations as involving tab and expanding subshells on space is probably a bad idea. However not sure it can work for completions either because you can already complete variable names without expanding them.

It could be useful though. Like I imagine doing rm *.png, expanding the wildcard and removing some of the files from the list.

How about this: we have a generic "expansion" or "abbreviation" system similar to the completions system; we bind CTRL-X or something for expanding tokens; and in command position we also expand abbreviations automatically. That could also make the sudo and git use cases work less obtrusively by making those expansions explicit.

It's a much bigger proposal than my original idea, though. 😉

Contributor

dag commented May 14, 2013

Thoughts on your thoughts!

Should it be automatic by using space or should it be triggered by an option via tab, or something else?

I don't think this works with anything but space (and enter) because the whole point is to get the seamless experience you get with aliases where you don't have to think about something being an alias or not, and tab doesn't work either because g<Tab> should complete commands that begin with a g. If we add a new binding say CTRL-X we now have three types of completions: normal ones, autosuggestions and abbreviations. I really think this needs to be done with space or not at all.

Should it only be for simple strings ex g for git?

In command position it should be possible to include arguments in an abbreviation. For example gc expanding to git commit --all or what have you. Basically I think of abbreviations as being exactly like aliases, except they expand live on the command line.

Should it only be applicable for the first item on the commandline, or anywhere?

Only in command position is probably a good start. Then we can maybe experiment with the argument position use cases I suggested before.

Should it be possible to do string -> value conversions ex d for current date Tue May 14 20:23:03 CEST 2013?

You mean in argument position? echo d expanding to echo the date? I really think if we do argument position abbreviations at all, it needs to be used very conservatively and only when either the argument is a command (as in the case of sudo) or when the command has its own alias system (as in the case of git) and expanding would have the exact same effect as not expanding (so we only expand for usability).

Should it be possible to expand subshells ex vim (find . -iname '*cfg')<tab>

I think that's a question for completions and not abbreviations, as I don't think of abbreviations as involving tab and expanding subshells on space is probably a bad idea. However not sure it can work for completions either because you can already complete variable names without expanding them.

It could be useful though. Like I imagine doing rm *.png, expanding the wildcard and removing some of the files from the list.

How about this: we have a generic "expansion" or "abbreviation" system similar to the completions system; we bind CTRL-X or something for expanding tokens; and in command position we also expand abbreviations automatically. That could also make the sudo and git use cases work less obtrusively by making those expansions explicit.

It's a much bigger proposal than my original idea, though. 😉

@gustafj

This comment has been minimized.

Show comment
Hide comment
@gustafj

gustafj May 15, 2013

Contributor

Space as trigger sounds good to me, probably gives the best user experience.
Expanding *.png sounds interesting ;)
I myself don't like a lot of different bindings for different things, perhaps "double tab" could be used instead of a new binding.
Ex ....*.png<tab> gives press <tab> again to expand *.png (the same for subshells).

But it might be better to limit this proposal to: abbreviations for the command position, expanding using space.
And have "expand subshells/wildcards" & sudo support as a separate one?

Contributor

gustafj commented May 15, 2013

Space as trigger sounds good to me, probably gives the best user experience.
Expanding *.png sounds interesting ;)
I myself don't like a lot of different bindings for different things, perhaps "double tab" could be used instead of a new binding.
Ex ....*.png<tab> gives press <tab> again to expand *.png (the same for subshells).

But it might be better to limit this proposal to: abbreviations for the command position, expanding using space.
And have "expand subshells/wildcards" & sudo support as a separate one?

@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag May 15, 2013

Contributor

Not sure double tab would work as that currently cycles between completions. Vim seems to have CTRL+] for expanding abbreviations without typing a space...

I think if we do live expansions at all, then abbreviations should be implemented with that somehow, so the ideas are related. But if we don't do live expansions, abbreviations should still be considered on their own. So not sure what to do here. :-)

Contributor

dag commented May 15, 2013

Not sure double tab would work as that currently cycles between completions. Vim seems to have CTRL+] for expanding abbreviations without typing a space...

I think if we do live expansions at all, then abbreviations should be implemented with that somehow, so the ideas are related. But if we don't do live expansions, abbreviations should still be considered on their own. So not sure what to do here. :-)

@gustafj

This comment has been minimized.

Show comment
Hide comment
@gustafj

gustafj May 16, 2013

Contributor

Yeah your right about <tab>, was only thinking for subshells (where it currently does nothing).
It could be possible to change the current behavior of <anything><space><tab> which currently cycles through all available files in the current dir (first printing them all).
Ex

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

But i would rather have "live expansions" using a new key-combo than living without it ;)
Expanding *.cfg to a.cfg b.cfg c.cfg d.cfg feels really useful.
But then all forms of possible expansions should be expandable, not just wildcards, ex brace completion (which i would rather see removed ... but that is a different issue #354)

Contributor

gustafj commented May 16, 2013

Yeah your right about <tab>, was only thinking for subshells (where it currently does nothing).
It could be possible to change the current behavior of <anything><space><tab> which currently cycles through all available files in the current dir (first printing them all).
Ex

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

But i would rather have "live expansions" using a new key-combo than living without it ;)
Expanding *.cfg to a.cfg b.cfg c.cfg d.cfg feels really useful.
But then all forms of possible expansions should be expandable, not just wildcards, ex brace completion (which i would rather see removed ... but that is a different issue #354)

@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag May 16, 2013

Contributor

But then all forms of possible expansions should be expandable, not just wildcards, ex brace completion (which i would rather see removed ... but that is a different issue #354)

Agreed on both accounts. I wonder if double quotes should be expandable too... echo "hello $USER" -> echo "hello dag".

Contributor

dag commented May 16, 2013

But then all forms of possible expansions should be expandable, not just wildcards, ex brace completion (which i would rather see removed ... but that is a different issue #354)

Agreed on both accounts. I wonder if double quotes should be expandable too... echo "hello $USER" -> echo "hello dag".

@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag May 16, 2013

Contributor

I think what we're talking about here is actually "evaluation" more than "expanding" while on the other hand abbreviations are not about evaluation, so these ideas are probably separate and I'll make a new issue for the other one and edit this one a bit.

Contributor

dag commented May 16, 2013

I think what we're talking about here is actually "evaluation" more than "expanding" while on the other hand abbreviations are not about evaluation, so these ideas are probably separate and I'll make a new issue for the other one and edit this one a bit.

@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag May 19, 2013

Contributor

Here's a basic working prototype:

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'

One problem I noticed is that if you hit enter to execute an abbreviated commandline, the expanded form is highlighted as an error (unknown command), even including the arguments.

Contributor

dag commented May 19, 2013

Here's a basic working prototype:

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'

One problem I noticed is that if you hit enter to execute an abbreviated commandline, the expanded form is highlighted as an error (unknown command), even including the arguments.

@terlar

This comment has been minimized.

Show comment
Hide comment
@terlar

terlar May 19, 2013

Contributor

I liked this so much, so I implemented a way to manage these abbreviations.

In the end I think these should be handled the same way completions and functions are handled. With it's own abbreviations folder where it can be saved.

This is the current implementation:

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

Then you do something like this:

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

Update 1: Add ability to remove abbreviations and store them in a universal variable.
Update 2: Create functions for abbreviations also

Contributor

terlar commented May 19, 2013

I liked this so much, so I implemented a way to manage these abbreviations.

In the end I think these should be handled the same way completions and functions are handled. With it's own abbreviations folder where it can be saved.

This is the current implementation:

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

Then you do something like this:

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

Update 1: Add ability to remove abbreviations and store them in a universal variable.
Update 2: Create functions for abbreviations also

@terlar

This comment has been minimized.

Show comment
Hide comment
@terlar

terlar May 19, 2013

Contributor

Looking at how functions work, we could introduce:

  • abbred
  • abbrsave

Which would basically be to clone those functions.

Contributor

terlar commented May 19, 2013

Looking at how functions work, we could introduce:

  • abbred
  • abbrsave

Which would basically be to clone those functions.

@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag May 20, 2013

Contributor

Nice! I'm not quite convinced we need a ~/.config/fish/abbreviations directory and the accompanying abbr{ed,save}, though. Unlike functions and completions, they're not really slow to load individually and they only need a single line to be defined. I think they're more like bind, perhaps we could have a fish_[user_]abbreviations function like the fish_user_key_bindings function, that loads the first time fish tries to expand an abbreviation? ([user_] for consistency but I'm not sure we should ship any default abbreviations?)

Only reason I can think of for having multiple files for abbreviations is if you have say an abbreviation for every git command in existence and some with arguments, so you want those separate from any others. But that's not how lazy-loading functions and completions work: they're loaded based on the command name, so if we did that for abbreviations we'd end up with one file for each abbreviation, each file containing only a single line of code!

Another idea is to do something like the universal variables, perhaps even by actually using universals (like set -U fish_abbreviations). Perhaps there is a use case for host-local abbreviations? Not sure.

Contributor

dag commented May 20, 2013

Nice! I'm not quite convinced we need a ~/.config/fish/abbreviations directory and the accompanying abbr{ed,save}, though. Unlike functions and completions, they're not really slow to load individually and they only need a single line to be defined. I think they're more like bind, perhaps we could have a fish_[user_]abbreviations function like the fish_user_key_bindings function, that loads the first time fish tries to expand an abbreviation? ([user_] for consistency but I'm not sure we should ship any default abbreviations?)

Only reason I can think of for having multiple files for abbreviations is if you have say an abbreviation for every git command in existence and some with arguments, so you want those separate from any others. But that's not how lazy-loading functions and completions work: they're loaded based on the command name, so if we did that for abbreviations we'd end up with one file for each abbreviation, each file containing only a single line of code!

Another idea is to do something like the universal variables, perhaps even by actually using universals (like set -U fish_abbreviations). Perhaps there is a use case for host-local abbreviations? Not sure.

@terlar

This comment has been minimized.

Show comment
Hide comment
@terlar

terlar May 20, 2013

Contributor

You have some good points and I'm leaning towards the fish_user_abbreviations way.

The other approach would be to have like completions where you put all related abbreviations into a file, but that might be harder to map.

I was planning to use set -U fish_abbreviations at first, but I like to have the config maintained by git, so prefer setting them somewhere, like a config. But the nice thing with a universal variable would be that you can add completions on the fly without any hazle, like (abbred, abbrsave). Just do a abbreviate.

One solution would be to let the command make sure abbreviations are uniquely added and overwrites existing ones. Then it would be bootstrapped with the fish_user_abbreviations and users can add custom ones to the universal variable if they want.

I have this right now:
set -q fish_abbreviations ; or fish_user_abbreviations

But that won't work if I keep maintaining the file.

Contributor

terlar commented May 20, 2013

You have some good points and I'm leaning towards the fish_user_abbreviations way.

The other approach would be to have like completions where you put all related abbreviations into a file, but that might be harder to map.

I was planning to use set -U fish_abbreviations at first, but I like to have the config maintained by git, so prefer setting them somewhere, like a config. But the nice thing with a universal variable would be that you can add completions on the fly without any hazle, like (abbred, abbrsave). Just do a abbreviate.

One solution would be to let the command make sure abbreviations are uniquely added and overwrites existing ones. Then it would be bootstrapped with the fish_user_abbreviations and users can add custom ones to the universal variable if they want.

I have this right now:
set -q fish_abbreviations ; or fish_user_abbreviations

But that won't work if I keep maintaining the file.

@terlar

This comment has been minimized.

Show comment
Hide comment
@terlar

terlar May 20, 2013

Contributor

Updated my previous functions to use universal variable and added possibility to erase them and also check before adding new ones if they exist.

I was thinking about making it more interactive, like asking if it should replace the current abbreviation. But since it might also be scripted, I didn't want to do that. I will look into the determination of interactive mode.

Contributor

terlar commented May 20, 2013

Updated my previous functions to use universal variable and added possibility to erase them and also check before adding new ones if they exist.

I was thinking about making it more interactive, like asking if it should replace the current abbreviation. But since it might also be scripted, I didn't want to do that. I will look into the determination of interactive mode.

@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag May 20, 2013

Contributor

Well see thing with completions is that even they're loaded for a single command. If the current command line process is git then completions/git.fish is loaded. When you have separate command names, you have to make separate files, see for example the completions for [ef]grep which are actually in a function that's called from each of those three completion files.

With abbreviations I don't see any way to know from the abbreviation which file to load, unless the file name is the abbreviation. And then you can't have multiple abbreviations in one file. I guess we could load all abbreviation files on start, or on first attempt to expand abbreviations, but that's different from how functions and completions are loaded, and could potentially be slow if you have many abbreviation files.

New idea: abbreviate -U to make a universal abbreviation, and abbreviate -g or just abbreviate to make a global one? If we do that, perhaps we should consider doing it for bind too...

Contributor

dag commented May 20, 2013

Well see thing with completions is that even they're loaded for a single command. If the current command line process is git then completions/git.fish is loaded. When you have separate command names, you have to make separate files, see for example the completions for [ef]grep which are actually in a function that's called from each of those three completion files.

With abbreviations I don't see any way to know from the abbreviation which file to load, unless the file name is the abbreviation. And then you can't have multiple abbreviations in one file. I guess we could load all abbreviation files on start, or on first attempt to expand abbreviations, but that's different from how functions and completions are loaded, and could potentially be slow if you have many abbreviation files.

New idea: abbreviate -U to make a universal abbreviation, and abbreviate -g or just abbreviate to make a global one? If we do that, perhaps we should consider doing it for bind too...

@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag May 20, 2013

Contributor

Also I think abbreviate should just overwrite any existing abbreviation, same as bind and function and set...

Contributor

dag commented May 20, 2013

Also I think abbreviate should just overwrite any existing abbreviation, same as bind and function and set...

@terlar

This comment has been minimized.

Show comment
Hide comment
@terlar

terlar May 20, 2013

Contributor

All are valid points. I think it makes sense to just overwrite like all other functions do.

I also like the suggestion with universal and global, which gives flexibility to choose how to handle your abbreviations/bindings. I'm not entirely sure how to implement that though, and I'm thinking maybe this should be a builtin to enhance the performance?

Contributor

terlar commented May 20, 2013

All are valid points. I think it makes sense to just overwrite like all other functions do.

I also like the suggestion with universal and global, which gives flexibility to choose how to handle your abbreviations/bindings. I'm not entirely sure how to implement that though, and I'm thinking maybe this should be a builtin to enhance the performance?

@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag May 20, 2013

Contributor

Yeah, I was only prototyping it in fish scripting for trying it out. Probably don't want slow scripting to fire every time you type a space. 😉

Contributor

dag commented May 20, 2013

Yeah, I was only prototyping it in fish scripting for trying it out. Probably don't want slow scripting to fire every time you type a space. 😉

@terlar

This comment has been minimized.

Show comment
Hide comment
@terlar

terlar May 20, 2013

Contributor

Yeah, still working great. I have been using it for about 1 day now and cannot imagine myself live without it anymore, haha 😁

Contributor

terlar commented May 20, 2013

Yeah, still working great. I have been using it for about 1 day now and cannot imagine myself live without it anymore, haha 😁

@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag May 20, 2013

Contributor

😊

Another problem I've noticed though is that if you do C-a on a non-empty commandline and type an abbreviation, it's not expanded on space since you're in the middle of a word. So say you do make install oops need root C-a ! now you have ![cursor]make install and typing the space doesn't expand the ! abbreviation. I'm gonna try to work around this with commandline -C.

A third problem, which might be a feature, is that it's only expanded when you type a space or enter after an abbreviation. So not for example if you type a space then C-a ! C-e. This could be a feature because it makes it possible to avoid abbreviation expansion, but I think it's a bit unfishy and we should instead have like a command to run a command line literally, bit like the command command but also accounting for shell functions and builtins. Or some special syntax, like \g in command position is interpreted as g and not expanded. Special syntax isn't really fishy either, but we already have space before the command special cased to mean "don't log in history", so shrug.

Fourth, and this one is an obscure one, if you do like in the previous paragraph so you have an unexpanded abbreviation followed by a space, then do C-a and space, the abbreviation is expanded and an extra space is inserted after it! Again, may need to check cursor position with commandline -C.

Oh and, the first problem I mentioned in a previous comment, it only happens if the unexpanded abbreviation is an unknown command. So a gc abbreviation expands to git commit and the whole thing highlights as an error, on hitting enter (without a space), but a gs abbreviation expands to git status and highlights correctly, because apparently I have ghostscript installed:

> which gs
/usr/bin/gs

I'm also wondering if maybe abbreviations should highlight as known "commands" even before you hit space... Currently if I type g it's red until type a space, but if I type git it highlights as known even before a space.

All these problems could probably be dealt with better if we do this in the C++ parts.

Contributor

dag commented May 20, 2013

😊

Another problem I've noticed though is that if you do C-a on a non-empty commandline and type an abbreviation, it's not expanded on space since you're in the middle of a word. So say you do make install oops need root C-a ! now you have ![cursor]make install and typing the space doesn't expand the ! abbreviation. I'm gonna try to work around this with commandline -C.

A third problem, which might be a feature, is that it's only expanded when you type a space or enter after an abbreviation. So not for example if you type a space then C-a ! C-e. This could be a feature because it makes it possible to avoid abbreviation expansion, but I think it's a bit unfishy and we should instead have like a command to run a command line literally, bit like the command command but also accounting for shell functions and builtins. Or some special syntax, like \g in command position is interpreted as g and not expanded. Special syntax isn't really fishy either, but we already have space before the command special cased to mean "don't log in history", so shrug.

Fourth, and this one is an obscure one, if you do like in the previous paragraph so you have an unexpanded abbreviation followed by a space, then do C-a and space, the abbreviation is expanded and an extra space is inserted after it! Again, may need to check cursor position with commandline -C.

Oh and, the first problem I mentioned in a previous comment, it only happens if the unexpanded abbreviation is an unknown command. So a gc abbreviation expands to git commit and the whole thing highlights as an error, on hitting enter (without a space), but a gs abbreviation expands to git status and highlights correctly, because apparently I have ghostscript installed:

> which gs
/usr/bin/gs

I'm also wondering if maybe abbreviations should highlight as known "commands" even before you hit space... Currently if I type g it's red until type a space, but if I type git it highlights as known even before a space.

All these problems could probably be dealt with better if we do this in the C++ parts.

@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag May 20, 2013

Contributor

Silly workaround for syntax highlighting problems: make an alias/function for every abbreviation. 😆

Actually, maybe that's a good idea to do anyway, hm... Means abbreviations will work in scripts, in eval, with type... Not sure.

Contributor

dag commented May 20, 2013

Silly workaround for syntax highlighting problems: make an alias/function for every abbreviation. 😆

Actually, maybe that's a good idea to do anyway, hm... Means abbreviations will work in scripts, in eval, with type... Not sure.

@terlar

This comment has been minimized.

Show comment
Hide comment
@terlar

terlar May 27, 2013

Contributor

Your workaround is what I am using currently, but I'm not sure if that is what it should do in the end, or if they should be intended to be used inside eval or type. For me they should be an input thing only. But I guess it might not hurt to also let them be run to get easy support for say sudo.

So I have been using the current implementation for a while now and these are the problems discovered with this solution so far (they are not related to the approach 👍):

  1. When pasting text, the last space gets inserted at the beginning of the line, e.g. echo this is a test becomes _echo this is atest when pasted, where _ is a space.
  2. When using read builtin the bindings on enter and space applies there also. So for example if I want to input some non command to read it will expand. I guess in the final implementation this should be off by default and enabled by read -s
  3. It is a little bit slow (~0.25-0.5 seconds)
Contributor

terlar commented May 27, 2013

Your workaround is what I am using currently, but I'm not sure if that is what it should do in the end, or if they should be intended to be used inside eval or type. For me they should be an input thing only. But I guess it might not hurt to also let them be run to get easy support for say sudo.

So I have been using the current implementation for a while now and these are the problems discovered with this solution so far (they are not related to the approach 👍):

  1. When pasting text, the last space gets inserted at the beginning of the line, e.g. echo this is a test becomes _echo this is atest when pasted, where _ is a space.
  2. When using read builtin the bindings on enter and space applies there also. So for example if I want to input some non command to read it will expand. I guess in the final implementation this should be off by default and enabled by read -s
  3. It is a little bit slow (~0.25-0.5 seconds)
@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag May 27, 2013

Contributor

You can work around 1. by pasting with C-y.

Contributor

dag commented May 27, 2013

You can work around 1. by pasting with C-y.

@terlar

This comment has been minimized.

Show comment
Hide comment
@terlar

terlar May 27, 2013

Contributor

For me C-y only pastes within fish (from what is cut inside fish) and not from my system clipboard. Copying between terminals or other apps.

Contributor

terlar commented May 27, 2013

For me C-y only pastes within fish (from what is cut inside fish) and not from my system clipboard. Copying between terminals or other apps.

@ridiculousfish

This comment has been minimized.

Show comment
Hide comment
@ridiculousfish

ridiculousfish May 28, 2013

Member

I think abbreviations are a really cool idea.

Member

ridiculousfish commented May 28, 2013

I think abbreviations are a really cool idea.

@ridiculousfish

This comment has been minimized.

Show comment
Hide comment
@ridiculousfish

ridiculousfish Jul 19, 2013

Member

I want to enable people to experiment with abbreviations to refine what the right behaviors should be. I checked in initial support for abbreviations into master as 92099c7 and f9c2a77.

An example of how to use it:

set -U fish_user_abbreviations 'gc=git checkout'
gc

gc will be expanded to "git checkout" on space or return.

Abbreviations are a list, so to add a new one:

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

Abbreviations expand in "command positions" (for example, in subshells or as arguments to if), but not as arguments. Abbreviations do not expand in scripts either.

Here are some unresolved issues for discussion:

  1. "Abbreviation" is long and hard to spell - can we find a better name? "Alias" would be good if it weren't already used for other things. One possibility is to invert it, e.g. "expansion." fish_user_expansions sounds OK to me.

  2. How should abbreviations be specified? The gc=git checkout syntax is lightweight but isn't used anywhere else in fish.

  3. We may want to not expand on enter, only space. Expanding on enter has the disadvantage that the user doesn't see what command they ran until after they've committed to running it. If we expand only on space, then users could type the abbreviation, followed by space, followed by enter, which doesn't seem too burdensome. A second possibility is to make the first enter trigger expansion, and the second enter actually execute it.

    On the other hand, if all abbreviations are specified by the user, then the chance of the user running something accidentally is low, so expanding on enter may be fine.

  4. The expanded form of an abbreviation is just a textual substitution, and does not have to itself be a valid command. For example, you can make an abbreviation that results in mismatched quotes or parenthesis. I think this is a potentially useful feature, but it means that fish cannot do syntax checking on code containing abbreviations, which will mean we may never be able to use them in scripts.

  5. Should the abbreviation expansion itself undergo subshell and variable expansion before substitution? I think yes, because that would make them immensely flexible. Abbreviations could then run arbitrary fish code.

  6. If I hit space, and the abbreviation expands and I changed my mind, maybe I should be able to hit delete and unexpand it.

Hopefully after living on them for a while, we'll know what feels right.

Member

ridiculousfish commented Jul 19, 2013

I want to enable people to experiment with abbreviations to refine what the right behaviors should be. I checked in initial support for abbreviations into master as 92099c7 and f9c2a77.

An example of how to use it:

set -U fish_user_abbreviations 'gc=git checkout'
gc

gc will be expanded to "git checkout" on space or return.

Abbreviations are a list, so to add a new one:

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

Abbreviations expand in "command positions" (for example, in subshells or as arguments to if), but not as arguments. Abbreviations do not expand in scripts either.

Here are some unresolved issues for discussion:

  1. "Abbreviation" is long and hard to spell - can we find a better name? "Alias" would be good if it weren't already used for other things. One possibility is to invert it, e.g. "expansion." fish_user_expansions sounds OK to me.

  2. How should abbreviations be specified? The gc=git checkout syntax is lightweight but isn't used anywhere else in fish.

  3. We may want to not expand on enter, only space. Expanding on enter has the disadvantage that the user doesn't see what command they ran until after they've committed to running it. If we expand only on space, then users could type the abbreviation, followed by space, followed by enter, which doesn't seem too burdensome. A second possibility is to make the first enter trigger expansion, and the second enter actually execute it.

    On the other hand, if all abbreviations are specified by the user, then the chance of the user running something accidentally is low, so expanding on enter may be fine.

  4. The expanded form of an abbreviation is just a textual substitution, and does not have to itself be a valid command. For example, you can make an abbreviation that results in mismatched quotes or parenthesis. I think this is a potentially useful feature, but it means that fish cannot do syntax checking on code containing abbreviations, which will mean we may never be able to use them in scripts.

  5. Should the abbreviation expansion itself undergo subshell and variable expansion before substitution? I think yes, because that would make them immensely flexible. Abbreviations could then run arbitrary fish code.

  6. If I hit space, and the abbreviation expands and I changed my mind, maybe I should be able to hit delete and unexpand it.

Hopefully after living on them for a while, we'll know what feels right.

@terlar

This comment has been minimized.

Show comment
Hide comment
@terlar

terlar Jul 20, 2013

Contributor

Thanks, I am running it now and it seems to work really well so far.

  1. We could use the abbreviation abbr for short. As for alias, if we think that is better, maybe it could be replaced with this behavior. If people want to use aliases in their scripts they could just do the function wrapping. Abbreviations seems to me exactly what people are using aliases for normally.
  2. I think it would be nice to have some helper functions to define and also remove abbreviations.
    For example: abbr gc 'git checkout' and abbr -e gc.
    It is a little bit cumbersome to do this manipulation through the variable in my opinion. Also it would be nice to assure that the abbreviations are unique. So you only have to define a new one to update it.
  3. I prefer the behavior that is now, many of my abbreviations like gs for git status would not be so useful if you would have to press space. However, I would be okay with double enter to actually execute it as you mentioned.
  4. Personally I'm fine with not using them in scripts.
  5. Yes, this would be cool. Cannot think of any abbreviation to use that on top of my head though.
  6. This is also a good idea, if I pressed space too early for an abbreviation for example. This would also go well together with the number 3 suggestion as double enter (still not sure if I want that extra enter though).
Contributor

terlar commented Jul 20, 2013

Thanks, I am running it now and it seems to work really well so far.

  1. We could use the abbreviation abbr for short. As for alias, if we think that is better, maybe it could be replaced with this behavior. If people want to use aliases in their scripts they could just do the function wrapping. Abbreviations seems to me exactly what people are using aliases for normally.
  2. I think it would be nice to have some helper functions to define and also remove abbreviations.
    For example: abbr gc 'git checkout' and abbr -e gc.
    It is a little bit cumbersome to do this manipulation through the variable in my opinion. Also it would be nice to assure that the abbreviations are unique. So you only have to define a new one to update it.
  3. I prefer the behavior that is now, many of my abbreviations like gs for git status would not be so useful if you would have to press space. However, I would be okay with double enter to actually execute it as you mentioned.
  4. Personally I'm fine with not using them in scripts.
  5. Yes, this would be cool. Cannot think of any abbreviation to use that on top of my head though.
  6. This is also a good idea, if I pressed space too early for an abbreviation for example. This would also go well together with the number 3 suggestion as double enter (still not sure if I want that extra enter though).
@xfix

This comment has been minimized.

Show comment
Hide comment
@xfix

xfix Jul 20, 2013

Member

alias is POSIX compatibility wrapper anyway. I don't have any problem with it doing abbreviations. If you write abbr gc 'git checkout' or something like that, you want completions for git checkout anyway.

Member

xfix commented Jul 20, 2013

alias is POSIX compatibility wrapper anyway. I don't have any problem with it doing abbreviations. If you write abbr gc 'git checkout' or something like that, you want completions for git checkout anyway.

@andreaseger

This comment has been minimized.

Show comment
Hide comment
@andreaseger

andreaseger Jul 20, 2013

Contributor

i used the script implementation from terlar for the last few weeks and switched to the new native version today so here are my two cents on the open points

  1. I think it would be a great idea to just letting alias do abbreviations now. As Bonus it would fix the not working completions on current aliases.
  2. what terlar said sounds good
  3. It would really bug me if I would need to double press enter on abbreviations to execute them. It would be kind of OK if they also work unexpanded like aliases with a single press of enter but then I have unexpanded abbreviations in my history
  4. --
  5. wouldn't variable expansion mean the content of the variables will be put into the command and therefor into your history? This would make the re-usability of such commands from history way lower as they no longer contain the variable but only their earlier content. Or did I misunderstand this point?
  6. I don't see myself using the unexpand feature as I don't use abbreviation longer than 3 chars which means they are all basically in muscle memory and it would be faster to just clear the current line. This might be different now seeing that the native implementation can be used anywhere and not only on the beginning of the line. But probably a good idea if it does not mean I have to always press space or double press enter to expand them.
Contributor

andreaseger commented Jul 20, 2013

i used the script implementation from terlar for the last few weeks and switched to the new native version today so here are my two cents on the open points

  1. I think it would be a great idea to just letting alias do abbreviations now. As Bonus it would fix the not working completions on current aliases.
  2. what terlar said sounds good
  3. It would really bug me if I would need to double press enter on abbreviations to execute them. It would be kind of OK if they also work unexpanded like aliases with a single press of enter but then I have unexpanded abbreviations in my history
  4. --
  5. wouldn't variable expansion mean the content of the variables will be put into the command and therefor into your history? This would make the re-usability of such commands from history way lower as they no longer contain the variable but only their earlier content. Or did I misunderstand this point?
  6. I don't see myself using the unexpand feature as I don't use abbreviation longer than 3 chars which means they are all basically in muscle memory and it would be faster to just clear the current line. This might be different now seeing that the native implementation can be used anywhere and not only on the beginning of the line. But probably a good idea if it does not mean I have to always press space or double press enter to expand them.
@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag Jul 20, 2013

Contributor

"Abbreviation" is long and hard to spell - can we find a better name? "Alias" would be good if it weren't already used for other things. One possibility is to invert it, e.g. "expansion." fish_user_expansions sounds OK to me.

Agreed, but not sold on "expansion".

How should abbreviations be specified? The gc=git checkout syntax is lightweight but isn't used anywhere else in fish.

It should simply be a new builtin, just like complete and bind or for that matter function that the user can call but whose underlying storage is opaque.

We may want to not expand on enter, only space. Expanding on enter has the disadvantage that the user doesn't see what command they ran until after they've committed to running it. If we expand only on space, then users could type the abbreviation, followed by space, followed by enter, which doesn't seem too burdensome. A second possibility is to make the first enter trigger expansion, and the second enter actually execute it.

I really think we want to expand on Enter. I imagine I'd get a lot of frustrating fish: Unknown command “gc” and I don't imagine I'd be alone in that. However, the expansion should happen on the command line, before it is executed, such that you will see the expansion in scrollback and it is the expanded form that ends up in the history.

Should the abbreviation expansion itself undergo subshell and variable expansion before substitution? I think yes, because that would make them immensely flexible. Abbreviations could then run arbitrary fish code.

I think it shouldn't. It would usually be preferable to have those expand at the time the command line is executed. Say I have an abbreviation for creating time-stamped notes. I type the abbreviation and a space, and it expands to something like vim 12:34:56.txt. Now, I don't run this command for a few seconds, and the time-stamp will be wrong. It would be better if the abbreviation expanded to vim (time +%T).txt. This does the right thing, and also means I have the option to edit the command line before executing it, for example to use a different time format. It also makes it repeatable; for example kill %firefox can be recalled from history and re-run even when the PID has changed. Lastly, I would argue that it's more consistent with the rest of fish, where the tokens on the command line are only evaluated at execution time.

On the other hand, evaluating at expansion time is strictly more powerful because we can opt out of it with for example escapes, but without it we can't really opt in. I think this would be better solved by #751 though, as it puts the user in control of evaluation. That still doesn't provide a way to get the exact moment of abbreviation expansion though; it would be the moment of the user expanding the individual token. Still, I do think it would be more useful and more consistent, as it would work not just with abbreviations but with any token on the commandline that can be evaluated, however it was added to the commandline.

If I hit space, and the abbreviation expands and I changed my mind, maybe I should be able to hit delete and unexpand it.

I think this should not be on delete or backspace, because part of my motivation for abbreviations is the ability to post-edit parts of the expansion before execution. Perhaps a better idea would be to add a binding for "delete backwards from cursor to current process" as defined by commandline -p. This would solve the problem with abbreviations (since they only expand in command position) but at the same time be really useful without abbreviations. This would work basically like Ctrl-U but stop at the start of the current "process". A variant corresponding to Ctrl-K that stops at the end of the current process could be added for consistency and might also be useful.

Contributor

dag commented Jul 20, 2013

"Abbreviation" is long and hard to spell - can we find a better name? "Alias" would be good if it weren't already used for other things. One possibility is to invert it, e.g. "expansion." fish_user_expansions sounds OK to me.

Agreed, but not sold on "expansion".

How should abbreviations be specified? The gc=git checkout syntax is lightweight but isn't used anywhere else in fish.

It should simply be a new builtin, just like complete and bind or for that matter function that the user can call but whose underlying storage is opaque.

We may want to not expand on enter, only space. Expanding on enter has the disadvantage that the user doesn't see what command they ran until after they've committed to running it. If we expand only on space, then users could type the abbreviation, followed by space, followed by enter, which doesn't seem too burdensome. A second possibility is to make the first enter trigger expansion, and the second enter actually execute it.

I really think we want to expand on Enter. I imagine I'd get a lot of frustrating fish: Unknown command “gc” and I don't imagine I'd be alone in that. However, the expansion should happen on the command line, before it is executed, such that you will see the expansion in scrollback and it is the expanded form that ends up in the history.

Should the abbreviation expansion itself undergo subshell and variable expansion before substitution? I think yes, because that would make them immensely flexible. Abbreviations could then run arbitrary fish code.

I think it shouldn't. It would usually be preferable to have those expand at the time the command line is executed. Say I have an abbreviation for creating time-stamped notes. I type the abbreviation and a space, and it expands to something like vim 12:34:56.txt. Now, I don't run this command for a few seconds, and the time-stamp will be wrong. It would be better if the abbreviation expanded to vim (time +%T).txt. This does the right thing, and also means I have the option to edit the command line before executing it, for example to use a different time format. It also makes it repeatable; for example kill %firefox can be recalled from history and re-run even when the PID has changed. Lastly, I would argue that it's more consistent with the rest of fish, where the tokens on the command line are only evaluated at execution time.

On the other hand, evaluating at expansion time is strictly more powerful because we can opt out of it with for example escapes, but without it we can't really opt in. I think this would be better solved by #751 though, as it puts the user in control of evaluation. That still doesn't provide a way to get the exact moment of abbreviation expansion though; it would be the moment of the user expanding the individual token. Still, I do think it would be more useful and more consistent, as it would work not just with abbreviations but with any token on the commandline that can be evaluated, however it was added to the commandline.

If I hit space, and the abbreviation expands and I changed my mind, maybe I should be able to hit delete and unexpand it.

I think this should not be on delete or backspace, because part of my motivation for abbreviations is the ability to post-edit parts of the expansion before execution. Perhaps a better idea would be to add a binding for "delete backwards from cursor to current process" as defined by commandline -p. This would solve the problem with abbreviations (since they only expand in command position) but at the same time be really useful without abbreviations. This would work basically like Ctrl-U but stop at the start of the current "process". A variant corresponding to Ctrl-K that stops at the end of the current process could be added for consistency and might also be useful.

@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag Jul 20, 2013

Contributor

This might be different now seeing that the native implementation can be used anywhere and not only on the beginning of the line.

I haven't tried @terlar's implementation but it is based on mine where expansions actually work properly in any command position, not just the start of line, kudos commandline -p. I'm actually in awe at how well my crude proof of concept code works! 🐟 ❤️

Contributor

dag commented Jul 20, 2013

This might be different now seeing that the native implementation can be used anywhere and not only on the beginning of the line.

I haven't tried @terlar's implementation but it is based on mine where expansions actually work properly in any command position, not just the start of line, kudos commandline -p. I'm actually in awe at how well my crude proof of concept code works! 🐟 ❤️

@andreaseger

This comment has been minimized.

Show comment
Hide comment
@andreaseger

andreaseger Jul 20, 2013

Contributor

hmm guess I never actually tried using abbreviations in other command positions.
Yeah the prototypes worked great only inconvenience I had was the mentioned pasting issue, but the feature was to good not to use it.

Contributor

andreaseger commented Jul 20, 2013

hmm guess I never actually tried using abbreviations in other command positions.
Yeah the prototypes worked great only inconvenience I had was the mentioned pasting issue, but the feature was to good not to use it.

@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag Jul 20, 2013

Contributor

@sch1zo Pasting should work if you use Ctrl-Y.

Contributor

dag commented Jul 20, 2013

@sch1zo Pasting should work if you use Ctrl-Y.

@andreaseger

This comment has been minimized.

Show comment
Hide comment
@andreaseger

andreaseger Jul 20, 2013

Contributor

that might be the case but most of the time I copy/pasted via selecting/middle click and there the issue was present. But the native implementation does not have that problem anymore and I already updated all my machines to use that one.

Contributor

andreaseger commented Jul 20, 2013

that might be the case but most of the time I copy/pasted via selecting/middle click and there the issue was present. But the native implementation does not have that problem anymore and I already updated all my machines to use that one.

@ridiculousfish

This comment has been minimized.

Show comment
Hide comment
@ridiculousfish

ridiculousfish Oct 11, 2014

Member

Space separator support is in fbade19

Member

ridiculousfish commented Oct 11, 2014

Space separator support is in fbade19

@kballard

This comment has been minimized.

Show comment
Hide comment
@kballard

kballard Oct 12, 2014

Contributor

If you hit space and it doesn't expand, then you know you didn't type it correctly. I'm not opposed to underlining or highlighting (it certainly would be an extra cue to let the user know why their commandline just changed), but I'm not sure I understand why you need to have confidence before hitting space.

Contributor

kballard commented Oct 12, 2014

If you hit space and it doesn't expand, then you know you didn't type it correctly. I'm not opposed to underlining or highlighting (it certainly would be an extra cue to let the user know why their commandline just changed), but I'm not sure I understand why you need to have confidence before hitting space.

@kballard

This comment has been minimized.

Show comment
Hide comment
@kballard

kballard Oct 12, 2014

Contributor

@ridiculousfish Regarding fbade19, abbreviations are new enough (and undocumented until recent master) that we should just remove the = support.

Contributor

kballard commented Oct 12, 2014

@ridiculousfish Regarding fbade19, abbreviations are new enough (and undocumented until recent master) that we should just remove the = support.

@ridiculousfish

This comment has been minimized.

Show comment
Hide comment
@ridiculousfish

ridiculousfish Oct 12, 2014

Member

I'm thinking about the before-return case, not the before-space case

Member

ridiculousfish commented Oct 12, 2014

I'm thinking about the before-return case, not the before-space case

@dag

This comment has been minimized.

Show comment
Hide comment
@dag

dag Oct 13, 2014

Contributor

Sounds good to me. I suppose it is possible to go overboard with highlighting, resulting in sluggishness and disorienting information overload, but I don't think that's the case here. Also, I presume, it would use some $fish_color_abbr-or-whatever variable so it could easily be disabled by those who so wish, for whatever reason.

Contributor

dag commented Oct 13, 2014

Sounds good to me. I suppose it is possible to go overboard with highlighting, resulting in sluggishness and disorienting information overload, but I don't think that's the case here. Also, I presume, it would use some $fish_color_abbr-or-whatever variable so it could easily be disabled by those who so wish, for whatever reason.

@binaryphile

This comment has been minimized.

Show comment
Hide comment
@binaryphile

binaryphile Oct 13, 2014

At first I was going to remark that I found it unintuitive that the highlighting behavior is different for abbreviations vs normal commands, until I realized I was incorrect and that it is consistent.

My confusion came from the fact that I was mixing up highlighting and the suggested-completion feature.

For example, when I type "echo", the highlighting is red until I type the full command, which is as it should be. However the suggested completion successfully anticipates what I was about to type and gives me reassurance that I'm heading in the intended direction.

I receive no such feedback for abbreviations, which is unfortunate since I can't frequently come up with memorable shortenings of commands, particularly the ones which expand to complex commands.

In fact, the goal for me is to pack a wide range of commands into a small namespace (I shoot for ~5 character abbreviations and have hundreds of them). Because of this, I rely even more heavily on shell guidance that I'm headed toward typing a valid command. Something that fulfills the role which suggested completion occupies, but for abbreviations instead of regular commands, would really be helpful, more so than for standard commands even for me.

I can see the difficulty for suggested completions posed by abbreviations. It would be unintuitive for the abbreviation to expand into the actual commands since it would no longer be contiguous with what you are typing. Still, I feel like it could be better than it is now.

At least for me, including the abbreviation itself (not the expansion) in the suggested completions would scratch my itch. I just want to see that I'm correctly typing a prefix of a defined abbreviation. That's enough to tell me that I'm not typing in vain because I've misremembered or mistyped my abbreviation.

At first I was going to remark that I found it unintuitive that the highlighting behavior is different for abbreviations vs normal commands, until I realized I was incorrect and that it is consistent.

My confusion came from the fact that I was mixing up highlighting and the suggested-completion feature.

For example, when I type "echo", the highlighting is red until I type the full command, which is as it should be. However the suggested completion successfully anticipates what I was about to type and gives me reassurance that I'm heading in the intended direction.

I receive no such feedback for abbreviations, which is unfortunate since I can't frequently come up with memorable shortenings of commands, particularly the ones which expand to complex commands.

In fact, the goal for me is to pack a wide range of commands into a small namespace (I shoot for ~5 character abbreviations and have hundreds of them). Because of this, I rely even more heavily on shell guidance that I'm headed toward typing a valid command. Something that fulfills the role which suggested completion occupies, but for abbreviations instead of regular commands, would really be helpful, more so than for standard commands even for me.

I can see the difficulty for suggested completions posed by abbreviations. It would be unintuitive for the abbreviation to expand into the actual commands since it would no longer be contiguous with what you are typing. Still, I feel like it could be better than it is now.

At least for me, including the abbreviation itself (not the expansion) in the suggested completions would scratch my itch. I just want to see that I'm correctly typing a prefix of a defined abbreviation. That's enough to tell me that I'm not typing in vain because I've misremembered or mistyped my abbreviation.

zanchey added a commit that referenced this issue Oct 17, 2014

web_config: add support for adding and editing abbreviations
Possible future enhancements include explanatory text and an image for
the 'save' action.

Work on #731.
@zanchey

This comment has been minimized.

Show comment
Hide comment
@zanchey

zanchey Nov 13, 2014

Member

I tried to extend abbr.fish to handle both spaces and = separators, but I haven't had a lot of success in coming up with a robust solution without shelling out to external tools.

Member

zanchey commented Nov 13, 2014

I tried to extend abbr.fish to handle both spaces and = separators, but I haven't had a lot of success in coming up with a robust solution without shelling out to external tools.

@ridiculousfish

This comment has been minimized.

Show comment
Hide comment
@ridiculousfish

ridiculousfish Nov 13, 2014

Member

I thought the plan was to remove the = support? I was thinking of just doing it, and then posting a message to the fish mailing list with a script that munges $fish_user_abbreviations that people could run to switch to spaces.

Member

ridiculousfish commented Nov 13, 2014

I thought the plan was to remove the = support? I was thinking of just doing it, and then posting a message to the fish mailing list with a script that munges $fish_user_abbreviations that people could run to switch to spaces.

zanchey added a commit that referenced this issue Nov 15, 2014

abbr/web_config: support space-delimited abbreviations
Support for space-delimited abbreviations was added to the expansion
parser in fbade19; this commit extends that support to the user-facing
tools, and documents the space-separated behaviour. Equals-delimited
abbreviations are expected to be removed before the next release.

Work on #731.

zanchey added a commit that referenced this issue Nov 16, 2014

abbr.fish: improve support for corner cases
Handle unusual cases ('=abc', ' =abc') better - regression from
8e8e6314due to a7bab7b.

Work on #731.

zanchey added a commit that referenced this issue Nov 16, 2014

abbr.fish: escape the output of abbr --show
Allows abbreviations containing embedded newlines, etc., to be displayed
and exported properly.

Work on #731.

zanchey added a commit that referenced this issue Nov 16, 2014

web_config: improve abbreviations support
 * Fetch abbreviations by reading the variable directly.
 * Use space separators for writing new abbreviations.

Work on #731.

@zanchey zanchey modified the milestones: next-minor, next-major Dec 1, 2014

@binaryphile

This comment has been minimized.

Show comment
Hide comment
@binaryphile

binaryphile Jan 6, 2015

Hey folks,

I wanted to make a note after having used abbreviations for quite some time now.

I'm a big fan, and they make my life much easier. I especially like the fact that other people can see what commands I'm issuing, in a familiar form.

My only dislike is that there is no history for abbreviations. Since I use abbreviations for almost every command, this has ended up with me losing history functionality for the most part. While you may think that abbreviations should be short enough to not need history functionality, I find myself missing it quite a bit. I have over 200 abbreviations defined, and some of them differ only slightly. Having history show me the one I issued yesterday, for example, would be immensely useful for the more involved and less-frequently used abbreviations. As I practically live with abbreviations, I've had to resort to using functions instead where I need history support since I really don't have history otherwise.

Thanks again for the feature.

Hey folks,

I wanted to make a note after having used abbreviations for quite some time now.

I'm a big fan, and they make my life much easier. I especially like the fact that other people can see what commands I'm issuing, in a familiar form.

My only dislike is that there is no history for abbreviations. Since I use abbreviations for almost every command, this has ended up with me losing history functionality for the most part. While you may think that abbreviations should be short enough to not need history functionality, I find myself missing it quite a bit. I have over 200 abbreviations defined, and some of them differ only slightly. Having history show me the one I issued yesterday, for example, would be immensely useful for the more involved and less-frequently used abbreviations. As I practically live with abbreviations, I've had to resort to using functions instead where I need history support since I really don't have history otherwise.

Thanks again for the feature.

@ridiculousfish

This comment has been minimized.

Show comment
Hide comment
@ridiculousfish

ridiculousfish Jan 6, 2015

Member

@binaryphile Very interesting. It sounds like you have an idea in mind of what this should look like (i.e. the UI). Would you like to describe it in more detail?

Member

ridiculousfish commented Jan 6, 2015

@binaryphile Very interesting. It sounds like you have an idea in mind of what this should look like (i.e. the UI). Would you like to describe it in more detail?

@binaryphile

This comment has been minimized.

Show comment
Hide comment
@binaryphile

binaryphile Jan 7, 2015

Good question. I guess I'd just like it that if any expansion were triggered then for the abbreviation to go into the history list. So if I my abbreviation were "gclon" for "git clone", then when i hit space (or semicolon), "gclon" would be added to my history. I wouldn't alter the normal behavior of storing the expanded command in history, so both would be available.

After that, when I began typing a prefix of the abbrev (such as "gcl"), I'd expect "gclon" to be the first option for autocompletion to pop up.

Ideally, at that point I'd be able to hit alt-f and have it both complete automatically to the expanded version, plus further offer a new autocompletion of that expanded command from history. I'd want that because I may have entered further arguments after expansion, and would want to have that available in as few keystrokes as possible via the same route I entered it in the first place (abbrev then arguments). Since the abbreviation in the history wouldn't have the arguments, alt-f would be the most natural method for me to move further along the completion argument by argument.

I think ctrl-f wouldn't change and would just move forward to the end of the abbreviation, not the expanded version, since there would be no visual cue as to what you'd be expanding to.

Good question. I guess I'd just like it that if any expansion were triggered then for the abbreviation to go into the history list. So if I my abbreviation were "gclon" for "git clone", then when i hit space (or semicolon), "gclon" would be added to my history. I wouldn't alter the normal behavior of storing the expanded command in history, so both would be available.

After that, when I began typing a prefix of the abbrev (such as "gcl"), I'd expect "gclon" to be the first option for autocompletion to pop up.

Ideally, at that point I'd be able to hit alt-f and have it both complete automatically to the expanded version, plus further offer a new autocompletion of that expanded command from history. I'd want that because I may have entered further arguments after expansion, and would want to have that available in as few keystrokes as possible via the same route I entered it in the first place (abbrev then arguments). Since the abbreviation in the history wouldn't have the arguments, alt-f would be the most natural method for me to move further along the completion argument by argument.

I think ctrl-f wouldn't change and would just move forward to the end of the abbreviation, not the expanded version, since there would be no visual cue as to what you'd be expanding to.

@ElijahLynn

This comment has been minimized.

Show comment
Hide comment
@ElijahLynn

ElijahLynn Mar 2, 2015

I just got a nightly build up and running to finally test this! I really like this feature and love the fact is has the abbr command that ships with it.

My feedback is that we need a good way to export for dotfile backup. I am thinking these should all go into one file in the format abbr --show outputs. abbr --show is good enough for me for now, I am just going to pipe them into a dotfile for now. But I do want an easy way to import them again when that time comes. So if Fish could import that format now that would be a good next step.

I just got a nightly build up and running to finally test this! I really like this feature and love the fact is has the abbr command that ships with it.

My feedback is that we need a good way to export for dotfile backup. I am thinking these should all go into one file in the format abbr --show outputs. abbr --show is good enough for me for now, I am just going to pipe them into a dotfile for now. But I do want an easy way to import them again when that time comes. So if Fish could import that format now that would be a good next step.

@ElijahLynn

This comment has been minimized.

Show comment
Hide comment
@ElijahLynn

ElijahLynn Mar 2, 2015

Following the command in the help to add a new abbreviation fails with this error.

selection_235

Following the command in the help to add a new abbreviation fails with this error.

selection_235

@zanchey

This comment has been minimized.

Show comment
Hide comment
@zanchey

zanchey Mar 6, 2015

Member

Currently you need to enter abbr -a "gco git checkout" but I think it would make more sense to support the case described in the manual.

Member

zanchey commented Mar 6, 2015

Currently you need to enter abbr -a "gco git checkout" but I think it would make more sense to support the case described in the manual.

@ElijahLynn

This comment has been minimized.

Show comment
Hide comment
@ElijahLynn

ElijahLynn Mar 6, 2015

Ahh, thanks!

Ahh, thanks!

@zanchey

This comment has been minimized.

Show comment
Hide comment
@zanchey

zanchey Mar 13, 2015

Member

48d3536 makes that change.

Member

zanchey commented Mar 13, 2015

48d3536 makes that change.

@zanchey

This comment has been minimized.

Show comment
Hide comment
@zanchey

zanchey Mar 13, 2015

Member

I think we should either leave the '=' separator support in the next minor release and disable it after that, or (silently?) upgrade people's fish_user_abbreviations.

Member

zanchey commented Mar 13, 2015

I think we should either leave the '=' separator support in the next minor release and disable it after that, or (silently?) upgrade people's fish_user_abbreviations.

@zanchey

This comment has been minimized.

Show comment
Hide comment
@zanchey

zanchey May 4, 2015

Member

I'm going to close this as fixed; I filed #2051 to track the migration. Many thanks to @dag for the concept and all those who tested it - looking forward to seeing this released soon!

Member

zanchey commented May 4, 2015

I'm going to close this as fixed; I filed #2051 to track the migration. Many thanks to @dag for the concept and all those who tested it - looking forward to seeing this released soon!

@zanchey zanchey closed this May 4, 2015

@ElijahLynn

This comment has been minimized.

Show comment
Hide comment
@ElijahLynn

ElijahLynn May 4, 2015

W00t, thanks everyone, I really LOVE this feature!!

W00t, thanks everyone, I really LOVE this feature!!

@dideler

This comment has been minimized.

Show comment
Hide comment
@dideler

dideler Jul 24, 2016

Contributor

I'm loving abbreviations, it's a much friendlier experience than aliases. Thanks so much!

I came across this thread while looking up how to store abbreviations in dotfiles1, 2.
If anyone stumbles here for the same reason, you can use abbr -s/--show. For example

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

dideler commented Jul 24, 2016

I'm loving abbreviations, it's a much friendlier experience than aliases. Thanks so much!

I came across this thread while looking up how to store abbreviations in dotfiles1, 2.
If anyone stumbles here for the same reason, you can use abbr -s/--show. For example

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

This comment has been minimized.

Show comment
Hide comment
@ElijahLynn

ElijahLynn Jul 25, 2016

@dideler I am using something similar to that for automated backup, I also recommend piping to sort.

abbr --show | sort > fish_abbreviation_backup;

I put everything into a fish_abbreviation_backup file and then add that to Homeshick for backup. It is all automated though and runs on cron. After I backup I source fish_abbreviation_backup so that fish shows alphabetical order when doing an abbr --show.

Would be nice if fish kept abbreviations in a file, similar to how it does things with functions.

update: Issue to sort abbreviations when storing them -> #2156

ElijahLynn commented Jul 25, 2016

@dideler I am using something similar to that for automated backup, I also recommend piping to sort.

abbr --show | sort > fish_abbreviation_backup;

I put everything into a fish_abbreviation_backup file and then add that to Homeshick for backup. It is all automated though and runs on cron. After I backup I source fish_abbreviation_backup so that fish shows alphabetical order when doing an abbr --show.

Would be nice if fish kept abbreviations in a file, similar to how it does things with functions.

update: Issue to sort abbreviations when storing them -> #2156

@krader1961

This comment has been minimized.

Show comment
Hide comment
@krader1961

krader1961 Jul 25, 2016

Contributor

Would be nice if fish kept abbreviations in a file...

From the man page: "Abbreviations are stored using universal variables." Which means you'll find them in the ~/.config/fish/fishd.macaddr file under var name fish_user_abbreviations. The abbr command simply manipulates that universal var.

Contributor

krader1961 commented Jul 25, 2016

Would be nice if fish kept abbreviations in a file...

From the man page: "Abbreviations are stored using universal variables." Which means you'll find them in the ~/.config/fish/fishd.macaddr file under var name fish_user_abbreviations. The abbr command simply manipulates that universal var.

@ElijahLynn

This comment has been minimized.

Show comment
Hide comment
@ElijahLynn

ElijahLynn Sep 2, 2016

Thanks, would it be okay to consider the idea of keeping them in ~/.config/fish/abbreviations.fish so we can add them easily to our dotfiles?

Thanks, would it be okay to consider the idea of keeping them in ~/.config/fish/abbreviations.fish so we can add them easily to our dotfiles?

@faho

This comment has been minimized.

Show comment
Hide comment
@faho

faho Sep 2, 2016

Member

@ElijahLynn: What I do is I have a file called "abbrs.fish" in ~/.config/fish/conf.d/, with the following contents:

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

I have this in my dotfiles, and I can just drop it into any machine I haven't yet used it on, and if I want to reset the abbrs, I can erase them all (I do set -e fish_user_abbreviations; set -e fish_initialized) and restart fish.

Member

faho commented Sep 2, 2016

@ElijahLynn: What I do is I have a file called "abbrs.fish" in ~/.config/fish/conf.d/, with the following contents:

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

I have this in my dotfiles, and I can just drop it into any machine I haven't yet used it on, and if I want to reset the abbrs, I can erase them all (I do set -e fish_user_abbreviations; set -e fish_initialized) and restart fish.

@ElijahLynn

This comment has been minimized.

Show comment
Hide comment
@ElijahLynn

ElijahLynn Sep 2, 2016

Thanks, I may be missing this but that looks like you need maintain that manually and don't get to add manage them easily with the abbr command.

Thanks, I may be missing this but that looks like you need maintain that manually and don't get to add manage them easily with the abbr command.

@faho

This comment has been minimized.

Show comment
Hide comment
@faho

faho Sep 2, 2016

Member

You add the abbr command there. This can even be the output of an abbr --show call.

Member

faho commented Sep 2, 2016

You add the abbr command there. This can even be the output of an abbr --show call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment