On Jun 21, 2012, at 12:41 PM, ridiculous_fish <corydo...@ridiculousfish.com> 
wrote:

> Hello Kevin,
> 
> Thank you for taking the time to write this up! Your git script looks very 
> ambitious, and so this is thoughtful, informed feedback. (Incidentally I just 
> merged your git script changes). Let me respond to each point in turn:
> 
> 1.2. 3.: Regarding string manipulation: I'm in favor of doing something here, 
> as long as it keeps in fish's spirit. i.e. definitely do NOT adopt the POSIX 
> specification for variable modifiers, like ${a##*/} to strip all leading path 
> components from $a. That's just line noise, and we can do way better.

That's fine. I'm not arguing that we need bash's syntax, just its functionality.

> I also like your suggestion of supporting "$(…)", especially because this is 
> currently a syntax error, so there's no compatibility risk.  There's some 
> synergy between this and string manipulation. There could be a built-in "str" 
> or "munge" or whatever that manipulates its argument based on other 
> parameters, e.g. "(munge --strip '/*' --repeat $PWD)" to get the last 
> component of pwd.

That would be nice. I'm mildly worried about verbosity here, because "(munge 
--strip '/*' --repeat $PWD)" is much longer than "${PWD#/*}", but hopefully we 
can find a fairly simple way to do this.

> But we ought not to invent yet another string manipulation syntax. If anyone 
> has any suggestions for an existing command-based string manipulation syntax 
> that would be appropriate for fish, please share it.
> 
> 4. Can you elaborate on your math needs? Farming out to bc is slow, but I 
> haven't encountered a case where it matters.

In my __fish_git_prompt script, there's a bit where it replicates the behavior 
of --count on git versions that don't support it (this is turned on with a 
variable). The original __git_ps1 script iterated over each word in the command 
output, tested for a prefix of <, and incremented one of two variables 
depending on the results of that test. In Fish, not only would this have 
required invoking `cut` just to test for the prefix of <, but invoking `bc` 
just to increment one variable was far too slow to consider using in a prompt 
function (I ended up replacing it with a call to grep, which was then passed in 
to `count`).

Basically, if you do math once, you're fine. But if you're doing math in a 
loop, invoking `bc` every time is extremely slow.

I also have a separate function that emits a 256 color table, and it uses math 
to figure out the right color code. The bash script takes 0.01s. The fish 
script, which uses `bc`, takes almost a full second. I can't tell if `bc` is 
really the culprit here, but it's the only non-builtin I'm calling. This is 
documented in issue #152 (Need more builtins).

> 5. Extending builtin test with == for globbing seems reasonable; currently == 
> is a syntax error. Mapping [ to built-in test seems good too. Introducing [[ 
> is bad: [[ does some very magical things to its arguments (like not expanding 
> them) that can't be handled generically.

I don't think we should introduce [[, I just want `test` to handle ==. And it 
probably makes sense to map `[` to `test`.

> 6. Agreed regarding 'else if'. Any objection to 'elif' as seen in bash, 
> Python, and others?

Whenever a language uses a construct other than `else if`, I always have a hard 
time remembering exactly what it is. Is it `elseif`? `elsif`? `elif`? I 
typically have to rely on my editor's syntax colorizing to tell me when I've 
figured out the right token. Based on that, I would prefer to simply use 'else 
if', since that's not a valid construct today (and therefore would not be 
breaking anything), but if you have some reason to prefer 'elif' then I suppose 
that's fine.

> 7. I see your point regarding the difficulty of doing an assign-and-test, but 
> the construct 
> 
>   if set foo (some command)
>   …
> 
> appears to be checking the success of the set command, not of the subcommand. 
> Still I don't have any better suggestions - that's one to think about.

One other possibility is to introduce a separate variable that holds the status 
of the most recently executed subcommand, but that's still more awkward to use 
than I'd ideally like

    set foo (some command)
    if test $subcmdStatus -ne 0
        # do something
    end

I also forgot one item in my wishlist:

8. bash has $PIPESTATUS, which lets me get the status of any item in the most 
recently executed pipe. Fish could use something similar.

-Kevin

> _fish
> 
> On Jun 21, 2012, at 10:58 AM, Kevin Ballard wrote:
> 
>> During the process of porting __git_ps1 to Fish (see my previous email), I 
>> ran
>> into lots of issues (both design issues and missing functionality) with Fish
>> scripting. I've already filed issues for a lot of these, but I thought I 
>> would
>> just try to round them all up. These are in no particular order:
>> 
>> 1. Fish seriously needs some facility for doing basic string manipulation.
>> Farming out to other processes is rather slow and complicated. In fact, when 
>> I
>> needed to replicate bash's functionality for "${somevar#strip/prefix}", it
>> turned out the easiest way to do that was in fact to use bash again, with
>> (/bin/sh -c 'echo ${1#strip/prefix}' -- $somevar). Farming out to other 
>> programs
>> to do work, as slow as it is, is at least understandable, but having to 
>> actually
>> farm out to bash itself seems completely wrongheaded.
>> 
>> 2. Fish could really use an equivalent for bash's ${var:-value} syntax. It's
>> very awkward to turn what could be one expression into 4 lines is rather
>> awkward. And in fact in my __fish_git_prompt script, the lack of this
>> functionality ballooned into a lot more work because I didn't want to insert
>> those 4 lines everywhere I needed the simple characters. See the
>> __fish_git_prompt_validate_chars function from my __fish_git_prompt.fish 
>> script,
>> along with the extra event handler to invalidate those variables. This
>> functionality could have been used to simplify the color variable logic as 
>> well.
>> 
>> 3. Fish needs a way to do command substitution within a double-quoted string.
>> The simplest solution is probably to support $() within double-quotes. The
>> reasoning is twofold: first, a command substitution that evaluates to no 
>> output
>> ends up being stripped entirely from the argument list of its surrounding
>> command. This has extremely bad implications when using it with, e.g. `test 
>> -n
>> (some command)`. Second, this would allow for storing the output with its
>> newlines in a variable, instead of having the output be split into multiple
>> elements. And as a bonus it would make it a lot easier to combine command
>> substitution output with other text in the same argument, e.g. 
>> "$somevar"(some
>> command)"$anothervar".
>> 
>> 4. Fish needs basic math. Farming math out to `bc` is extremely slow.
>> 
>> 5. Fish needs a way to do string testing with pattern matching, e.g. the ==
>> operator from bash's [[ builtin.
>> 
>> 6. We need 'else if'. I can't figure out why that was omitted.
>> 
>> 7. A command substitution should be allowed to modify the $status of its
>> surrounding context. It's currently documented as not touching $status, 
>> although
>> this documentation is fairly unnecessary because if it did modify $status, 
>> that
>> would simply be overwritten by the status of the command that it's being 
>> passed
>> as an argument to. However, once command substitution can modify $status, 
>> then
>> the next step is to modify the `set` builtin to not modify $status unless the
>> `-q` flag was provided. With both of these changes, I can then store the 
>> command
>> output into a variable and act on its status. In bash, this is trivial:
>> 
>>      if foo="$(some command)"; then
>>              # the command substitution exited 0
>>      fi
>> 
>> In Fish, I'd really like to be able to say
>> 
>>      if set foo (some command)
>>              # the command substitution exited 0
>>      end
>> 
>> Instead I have to use the awkward construct
>> 
>>      set -l oldStatus
>>      set foo (some command; set oldStatus $status)
>>      if test $oldStatus -ne 0
>>              # the command substitution exited 0
>>      end
>> 
>> -Kevin
> 


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Fish-users mailing list
Fish-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/fish-users

Reply via email to