I work through the cookbook but get tripped up by the elvish syntax quickly
there's this example edit:rprompt = (constantly (edit:styled (whoami)✸(hostname) inverse)) and I just wanted to try to replace the ✸ so first I just wanted to delete it and then I get
Exception: arity mistmatch: want 2 arguments, got 3
got 3 args after I deleted one? how is that?
and then I tried edit:rprompt = (constantly (edit:styled (whoami) ">>" (hostname) inverse))
and now elvish gets 4 arguments huh
I like the idea of elvish but it's usability compared to modern languages seems to be a bit hit and miss or maybe the dice could be improved or I'm just stubborn?
it's also not clear to me why leaving out the inverse does not work, I'd expect this to be an optional argument.
thanks
and this confusion just continues like
edit:-matcher[''] = [p]{ edit:match-prefix &ignore-case $p }
the Fundamental were very easy nearly superfluous (as it should be) but now elvish is just throwing a bunch of weird symbols and unintuitive syntax at me with no comment? like what is that [''] supposed to do here, what is the & doing? (it's apparently all over the place just not defined afaik) actually just what is edit:-matcher ? a namespace or function or an elve goofing around..?
I find it is actually confusing and not so much Elvish is a friendly and expressive
your first example fn ls [@a]{ e:ls --color $@a } does not work for me btw but that is not a fault of elvish, my version of ls just has no --color option, not sure if that is special for me or if you have a special ls version. Probably BSD vs GNU but it's confusing because on another point you assume uname outputs Darwin in which case I'd not expect to have GNUs ls necessarily installed.
edit:rprompt = (constantly (edit:styled (whoami) ">>" (hostname) inverse))
These are 4 arguments indeed.
(whoami)">>"(hostname)inverseMaybe you want to get a username>>hostname string. In this case, you shouldn't leave spaces between the first 3 arguments, because spaces are argument separators: (whoami)">>"(hostname). If you want spaces in the prompt between the items, you should put spaces in the string literal: `" >> ".
got 3 args after I deleted one? how is that?
Because you didn't delete the character -- you replaced it with a space (given the error message) So you ended up passing three arguments to a function that only accepts two.
BTW, You'd get a similar failure using fish which is arguably a friendlier shell for people with limited programming experience. For example, here is a rough equivalent of what you were doing only using fish syntax:
$ function edit:style
echo arg 1: $argv[1]
echo arg 2: $argv[2]
echo arg count: (count $argv)
end
$ edit:style (whoami) (hostname) inverse 0 ms
arg 1: krader
arg 2: macbook.skepticism.us
arg count: 3
Notice the edit:style function got three arguments but was only expecting two.
Hi, I am sorry that you find Elvish's syntax confusing. Learning materials are indeed lacking in many places, partially because I need to priotize coding over documenting at the stage, and partially because it is not always clear to me which aspects warrant more documentation. Feedback is appreciated; they are very valuable for my priotization. Also, the reference documents are a little bit more complete, and I encourage you to read them as well.
Answering your particular questions (I will also clarify the points in the documents later):
I guess you removed the star symbol and replaced with a space? That will indeed make it three arguments: (whoami)✸(uname) is one argument because it runs together; if you remove ✸ it becomes two separate arguments. What you want is not (whoami) ">>" (uname), but rather (whoami)">>"(uname). This is true of other shells as well; in bash for example, ls $a.txt lists one file, but ls $a .txt lists two.
The empty string key in edit:-matcher stands for the default matcher. The right-hand-side is a lambda, [p] being the parameter. The &ignore-case syntax is for command options; somewhat like --ignore-case, but for builtin functions and user-defined functions.
Yeah the difference in ls flags is confusing. I will clarify that.
@monouser7dig It seems to me you are simply too lazy to read and understand the full documentation. Understanding something is organizing the knowledge. If you don't have knowledge, you can't organize it, so you don't understand it. So read the documentation.
The --color option of ls probably expects an argument that specifies when to use color (e.g. always, auto, never). You may want to try exa, which is a modern replacement for ls.
The '' in edit:-matcher[''] = [p]{ edit:match-prefix &ignore-case $p } means an empty string. The & specifies named arguments (called options) for Elvish lambdas. Options are not mandatory when you call a function, because they have a default value. You can use named arguments in your own functions also:
fn my_function [&first_opt="Default value" first_positonal_arg second_positional_arg &second_opt='This also has a default value.']{
echo "This is the function body."
# Options are accessible as variables:
echo $first_opt
# If the function was called without specifying &first_opt, the above line will print 'Default value', else it will print what was specified for it.
}
# This function can be also called as:
my_function &first_opt="string" &second_opt='another string' "This is the first positional arg." "This is the second positional arg"
# But it can be called without specifying any options (only giving positional args):
my_function first second
edit: is a namespace in edit:-matcher. The - in -matcher means that this function will change before 1.0 (the api, or only the internal implementation). If an external module is imported, it will be imported to a namespace.
you shouldn't leave spaces between the first 3 arguments, because spaces are argument separators:
@notramo thanks that makes some sense
@krader1961 it's not like I have no experience programming, it's just that the examples are confusing/ assume much implicitly that is not said. As notramo explains it actually makes sense, would be nice if that was easier to discover. I'm actually coming back to elvish the third time now because 1. I like the idea and 2. it was just too confusing before so I have done several attempts as I'm now doing a bit go anyway I was taking a look again.
The space thing is especially strange because earlier it's said that spaces in the input do not matter (echo Hello World)
@xiaq ok so what I still find confusing is the & thing what is it doing, it's also present in the map syntax?? thanks
I've even been doing some Haskell so I'd be inclined to say that if I do not understand it, chances are there are a couple other like me out there.
@notramo I actually read the docs and you'll find the BSD version of ls has no --color option if you read the docs/ manpage
sure '' is an empty string, but what is it doing in there? Is it telling the matcher to activate on an empty string? just would be nice to know.
- means unstable, ok, got it, thought everything before 1.0 would be subject to change eventually but ok, nice to know
IMO a shell should be as easy to learn as possible, I'm not programming to do bash scripting but bash scripting to get some stuff done. Bash is already awkward enough.
The structured data pipes/ multi assignment is nice and make my life easier but when I read about temporary assignment ... this just screams for implicit errors that are a pain to figure out when all I want to do is some script, not rocket science cpp.
Elements in braced lists can also be separated with whitespaces, or a combination of comma and whitespaces (the latter not recommended):
(In future, the syntax might be made more strict.)
yes PLEASE 👍 😄
@monouser7dig I hope your questions are answered now! As said above, I will make sure the documentations are improved. For further questions, discussion groups (listed on the repo homepage as well as https://elvish.io) can give you faster and more specific answers.
@krader1961 @notramo Thanks for chiming in!
One thing I do request is that we all strive to keep the conversation polite. Different people have different expectations, and Elvish is probably not going to make everyone happy (despite that being my wish). Let's work towards consensus, but if consensus is not reached, disagree respectfully.
sure, thanks, did not mean to sound rude, generally really appreciate your take on a new shell, was just torn between nice shell - language/ doc barrier
@monouser7dig I updated my above comment with links.
-means unstable, ok, got it, thought everything before 1.0 would be subject to change eventually but ok, nice to know
Everything is subject to change eventually, but these things will _surely_ change.
sure '' is an empty string, but what is it doing in there? Is it telling the matcher to activate on an empty string? just would be nice to know.
The edit:-matcher map contains the type of the completion (argument, variable, command, index etc.). If a completion type is not specified, (for example, the map don't have the argument key), the default matcher will be used (that is stored with the empty string key). The empty string don't have a special meaning, any key could be used for the fallback matcher (e.g. elephant, or default, or anything) , but @xiaq chose this.
By the way, @xiaq what about changing the key of the default matcher function from the empty string to something more obvious e.g. default or fallback in edit:-matcher?
@xiaq, Seems like this can be closed. The questions were answered and the documentation has been much improved since this issue was opened.
Most helpful comment
@monouser7dig I hope your questions are answered now! As said above, I will make sure the documentations are improved. For further questions, discussion groups (listed on the repo homepage as well as https://elvish.io) can give you faster and more specific answers.
@krader1961 @notramo Thanks for chiming in!
One thing I do request is that we all strive to keep the conversation polite. Different people have different expectations, and Elvish is probably not going to make everyone happy (despite that being my wish). Let's work towards consensus, but if consensus is not reached, disagree respectfully.