Re: [Fish-users] An idea, from implementing extended globbing in fish
2012/12/9 Cheer Xiao xiaqq...@gmail.com: Hi all, For those not acquainted with zsh: extended globbing is one of the many features of zsh that allows you to match files satisfying a given criteria in a inline manner (instead of going through a loop). For example, echo abc*(/) gives you all directories with names starting with abc in current directory, while rm .*(@) removes all symlinks with names starting with ., etc. It is a useful feature, but I don't really like the arcane syntax. Fish doesn't have extended globbing (which is good actually :-), so I'm tempted to write this: function filter set predicate $argv[1] for i in (seq 2 (count $argv)) test $predicate $argv[$i]; and echo $argv[$i] end end So now I write echo (filter -d abc*) and rm (filter -L .*) to achieve the same effect as echo abc*(/) and rm .*(@) in zsh. It is more verbose, but the readability is considerably better; it also allows you to reuse the knowledge of the test builtin. This works fine until, of course, you start to encounter file names containing newlines. Try this: cd (mktemp -d) mkdir 'a b' count * count (filter -d *) Clearly, The problem stems from the fact that when fish expands the command substitution (filter -d *), filenames echo'ed by filter run together before being split on newlines to render the substituted words. A newline in one of the filenames is then indistinguishable with two filenames. So this leads to my proposal: * When evaluating a fish function, maintain an alternative output buffer besides stdout. The buffer is actually a dynamic-sized list (std::vector for C++ programmers) of strings. Introduce a new builtin (say put) to write to that buffer. * Exactly one of the two output buffers (let's call them stdout and altout) should be active within a function. * Within functions, calling put activates the altout and closes stdout. Each invocation of put with k arguments appends k new elements to altout. (The relationship between altout and stdout still needs some thoughts though.) * When command substitution is performed, it is checked which of stdout and altout is active (the latter is only possible for fish functions; external commands always have only stdout active). If altout is active, the elements in altout are substituted directly. If stdout is active, the content in stdout is split on newlines before being substituted (as is currently done). * When altout is written to when there is no enclosing command substitution (eg. calling put on the prompt), anything written to it is directed to stdout plus a newline. With altout I can write my filter by replacing echo with put and it's now newline-safe. Being able to output arrays of strings can be of many other uses - actually it enables you to write any array manipulating functions in an easy way. If the newline-in-filenames stuff sounds too invented and unlikely, consider why shells need real arrays instead of strings joined by delimiters (be it whitespace or newlines) at all. Actually, one of the favorite things about fish is its clean array syntax, it is a really nice thing. I think fish deserves the added expressive power. :) Oops. Digging into the source, it turns out fish has no true array; instead array are strings joined with \x1e. This should be resolved first. I've opened an issue for that: https://github.com/fish-shell/fish-shell/issues/436 -- Regards, Cheer Xiao -- LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial Remotely access PCs and mobile devices and provide instant support Improve your efficiency, and focus on delivering more value-add services Discover what IT Professionals Know. Rescue delivers http://p.sf.net/sfu/logmein_12329d2d ___ Fish-users mailing list Fish-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/fish-users
Re: [Fish-users] An idea, from implementing extended globbing in fish
Hi Cheer, since you already use the additional function, it worth looking at the 'find' command, which can do all the complicated job which can not be done with simple globbing. regards, Maxim On Sun, 09 Dec 2012 17:43:59 +0400, Cheer Xiao xiaqq...@gmail.com wrote: Hi all, For those not acquainted with zsh: extended globbing is one of the many features of zsh that allows you to match files satisfying a given criteria in a inline manner (instead of going through a loop). For example, echo abc*(/) gives you all directories with names starting with abc in current directory, while rm .*(@) removes all symlinks with names starting with ., etc. It is a useful feature, but I don't really like the arcane syntax. Fish doesn't have extended globbing (which is good actually :-), so I'm tempted to write this: function filter set predicate $argv[1] for i in (seq 2 (count $argv)) test $predicate $argv[$i]; and echo $argv[$i] end end So now I write echo (filter -d abc*) and rm (filter -L .*) to achieve the same effect as echo abc*(/) and rm .*(@) in zsh. It is more verbose, but the readability is considerably better; it also allows you to reuse the knowledge of the test builtin. This works fine until, of course, you start to encounter file names containing newlines. Try this: cd (mktemp -d) mkdir 'a b' count * count (filter -d *) Clearly, The problem stems from the fact that when fish expands the command substitution (filter -d *), filenames echo'ed by filter run together before being split on newlines to render the substituted words. A newline in one of the filenames is then indistinguishable with two filenames. So this leads to my proposal: * When evaluating a fish function, maintain an alternative output buffer besides stdout. The buffer is actually a dynamic-sized list (std::vector for C++ programmers) of strings. Introduce a new builtin (say put) to write to that buffer. * Exactly one of the two output buffers (let's call them stdout and altout) should be active within a function. * Within functions, calling put activates the altout and closes stdout. Each invocation of put with k arguments appends k new elements to altout. (The relationship between altout and stdout still needs some thoughts though.) * When command substitution is performed, it is checked which of stdout and altout is active (the latter is only possible for fish functions; external commands always have only stdout active). If altout is active, the elements in altout are substituted directly. If stdout is active, the content in stdout is split on newlines before being substituted (as is currently done). * When altout is written to when there is no enclosing command substitution (eg. calling put on the prompt), anything written to it is directed to stdout plus a newline. With altout I can write my filter by replacing echo with put and it's now newline-safe. Being able to output arrays of strings can be of many other uses - actually it enables you to write any array manipulating functions in an easy way. If the newline-in-filenames stuff sounds too invented and unlikely, consider why shells need real arrays instead of strings joined by delimiters (be it whitespace or newlines) at all. Actually, one of the favorite things about fish is its clean array syntax, it is a really nice thing. I think fish deserves the added expressive power. :) -- Regards, Cheer Xiao -- LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial Remotely access PCs and mobile devices and provide instant support Improve your efficiency, and focus on delivering more value-add services Discover what IT Professionals Know. Rescue delivers http://p.sf.net/sfu/logmein_12329d2d ___ Fish-users mailing list Fish-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/fish-users -- LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial Remotely access PCs and mobile devices and provide instant support Improve your efficiency, and focus on delivering more value-add services Discover what IT Professionals Know. Rescue delivers http://p.sf.net/sfu/logmein_12329d2d ___ Fish-users mailing list Fish-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/fish-users
Re: [Fish-users] An idea, from implementing extended globbing in fish
2012/12/10 Maxim Gonchar gma...@gmail.com: Hi Cheer, since you already use the additional function, it worth looking at the 'find' command, which can do all the complicated job which can not be done with simple globbing. regards, Maxim On Sun, 09 Dec 2012 17:43:59 +0400, Cheer Xiao xiaqq...@gmail.com wrote: Hi all, For those not acquainted with zsh: extended globbing is one of the many features of zsh that allows you to match files satisfying a given criteria in a inline manner (instead of going through a loop). For example, echo abc*(/) gives you all directories with names starting with abc in current directory, while rm .*(@) removes all symlinks with names starting with ., etc. It is a useful feature, but I don't really like the arcane syntax. Fish doesn't have extended globbing (which is good actually :-), so I'm tempted to write this: function filter set predicate $argv[1] for i in (seq 2 (count $argv)) test $predicate $argv[$i]; and echo $argv[$i] end end So now I write echo (filter -d abc*) and rm (filter -L .*) to achieve the same effect as echo abc*(/) and rm .*(@) in zsh. It is more verbose, but the readability is considerably better; it also allows you to reuse the knowledge of the test builtin. This works fine until, of course, you start to encounter file names containing newlines. Try this: cd (mktemp -d) mkdir 'a b' count * count (filter -d *) Clearly, The problem stems from the fact that when fish expands the command substitution (filter -d *), filenames echo'ed by filter run together before being split on newlines to render the substituted words. A newline in one of the filenames is then indistinguishable with two filenames. So this leads to my proposal: * When evaluating a fish function, maintain an alternative output buffer besides stdout. The buffer is actually a dynamic-sized list (std::vector for C++ programmers) of strings. Introduce a new builtin (say put) to write to that buffer. * Exactly one of the two output buffers (let's call them stdout and altout) should be active within a function. * Within functions, calling put activates the altout and closes stdout. Each invocation of put with k arguments appends k new elements to altout. (The relationship between altout and stdout still needs some thoughts though.) * When command substitution is performed, it is checked which of stdout and altout is active (the latter is only possible for fish functions; external commands always have only stdout active). If altout is active, the elements in altout are substituted directly. If stdout is active, the content in stdout is split on newlines before being substituted (as is currently done). * When altout is written to when there is no enclosing command substitution (eg. calling put on the prompt), anything written to it is directed to stdout plus a newline. With altout I can write my filter by replacing echo with put and it's now newline-safe. Being able to output arrays of strings can be of many other uses - actually it enables you to write any array manipulating functions in an easy way. If the newline-in-filenames stuff sounds too invented and unlikely, consider why shells need real arrays instead of strings joined by delimiters (be it whitespace or newlines) at all. Actually, one of the favorite things about fish is its clean array syntax, it is a really nice thing. I think fish deserves the added expressive power. :) -- Regards, Cheer Xiao -- LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial Remotely access PCs and mobile devices and provide instant support Improve your efficiency, and focus on delivering more value-add services Discover what IT Professionals Know. Rescue delivers http://p.sf.net/sfu/logmein_12329d2d ___ Fish-users mailing list Fish-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/fish-users -- Regards, Cheer Xiao -- LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial Remotely access PCs and mobile devices and provide instant support Improve your efficiency, and focus on delivering more value-add services Discover what IT Professionals Know. Rescue delivers http://p.sf.net/sfu/logmein_12329d2d ___ Fish-users mailing list Fish-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/fish-users