Re: Strange compgen behaviour

2009-09-25 Thread Bernd Eggink

Mathias Dahl schrieb:

Hm, compgen appears to behave strange if words contain whitespace.
However, you don't need it, as you build the list yourself. Try this:

  _mm2() {
  local cur files
  cur=${COMP_WORDS[COMP_CWORD]}
  files=$(find /home/mathias/Videos/movies/ -iname $cur*.avi -type
f -printf %P\n)
  local IFS=$'\n'
  COMPREPLY=($files)
  }


Ah, you're right of course, I can do the matching myself. I have yet
another version working now (had to change your latest suggestion and
use grep for matching because -name does not like full paths which
becomes the case here):

_mm() {
local cur files
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
files=$(find /home/mathias/Videos/movies/ -iname *.avi -type f -
printf %p\n | grep ${cur})
local IFS=$'\n'
COMPREPLY=(${files})
}
complete -o filenames -F _mm mm

Now, this works almost. The remaining problem is that because `find'
finds file in subdirs (which I want, otherwise I could add the -
maxdepth option) as well, the `-o filenames' argument to `complete'
does not play well with it. I see the names of files in subdirs listed
when I type TAB (without path) but can never pick them without knowing
the name of the folder they are in.


Hm, I can't see any problem here. My version lets you pick any file in 
any subdir by simply typing the name (or part of it) without the 
directory part. After all, 'find -name' matches names, not paths (if you 
want to match full paths, use 'find -path'). I'd also rather use printf 
%P\n (capital P) instead of %p, the results look nicer (IMHO).


Regards,
Bernd

--
Bernd Eggink
http://sudrala.de




Re: Real easy questions. Please answer

2009-09-25 Thread Dave B
On Friday 25 September 2009 05:24:04 eatsubway wrote:
 sry i have a stupid question.

 I have a variable and need to know how many items are in it.

 for example:
 variable=abc xyz foo
 what program can i call to print out 3

 right now im doing this...

 Counter()
 {
   echo $#
 }
 Counter $IDs
 but that just seems stupid

Use an array, so you will even be able to store elements with spaces in them.

-- 
D.




Re: Real easy questions. Please answer

2009-09-25 Thread Chris F.A. Johnson
On Thu, 24 Sep 2009, eatsubway wrote:

 
 sry i have a stupid question.
 
 I have a variable and need to know how many items are in it.
 
 for example:
 variable=abc xyz foo
 what program can i call to print out 3
 
 right now im doing this...
 
 Counter()
 {
   echo $#
 }
 Counter $IDs
 but that just seems stupid

   That's a perfectly good way of doing it, but you will want to turn
   off filename expansion if there's a chance that the value may
   contain wildcards:

set -f
Counter $IDs
set +f

-- 
   Chris F.A. Johnson, webmaster http://woodbine-gerrard.com
   ===
   Author:
   Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)




Re: Strange compgen behaviour

2009-09-25 Thread Mathias Dahl
 Hm, I can't see any problem here. My version lets you pick any file in
 any subdir by simply typing the name (or part of it) without the
 directory part. After all, 'find -name' matches names, not paths (if you
 want to match full paths, use 'find -path'). I'd also rather use printf
 %P\n (capital P) instead of %p, the results look nicer (IMHO).

When I try with %P it works (better). However, when I do that and use
the -o filenames option I see only the filenames of the sub folders
and sometimes that name does not reflect what it is as well as the
folder does (if for example I have a folder called Cool Movie 2 and in
it a file called thefile.avi). So, it seems I did not really want what
I thought I wanted from the beginning :) The output I get now looks
like this:

...
filie_in_root_folder.avi
Some sub folder/file_in_sub_folder.avi
...

The only annoyance now is the hardcoded quoting (to handle spaces and
other bad chars) I do using sed, but I guess I have to live with it.

This has been an interesting topic!

/Mathias


Re: Strange compgen behaviour

2009-09-25 Thread Mathias Dahl
 This has been an interesting topic!

I thought I should share the final version as well:

_mm() {
local cur files
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
files=$(find /home/mathias/Videos/movies/ -iname *.avi -type f -
printf %P\n | grep ${cur} | sed s/\\([][\\(\\) ,\']\\)/\\1/
g)
local IFS=$'\n'
COMPREPLY=(${files})
}

complete -F _mm mm

And the `mm' script needs to append the root folder, of course, like
so:

#!/bin/bash
mplayer /home/mathias/Videos/movies/$1

Works quite well. Maybe it will be useful to someone else too.

/Mathias


Re: Strange compgen behaviour

2009-09-25 Thread Mathias Dahl

 printf %q $filename

 will either insert backslashes in front of all the shell metacharacters,
 or $'...' quote the whole thing, or take some other action which renders
 a string safe.  It's basically the opposite of eval.

Interesting! Can I make it part of my pipe (in place of `sed') or need
I change it to a for or while loop? This is what I have now:

files=$(find /home/mathias/Videos/movies/ -iname *.avi -type f -
printf %P\n | grep ${cur} | sed s/\\([][\\(\\) ,\']\\)/\\1/
g)

/Mathias


Re: Strange compgen behaviour

2009-09-25 Thread Mathias Dahl
 Interesting! Can I make it part of my pipe (in place of `sed') or need
 I change it to a for or while loop? This is what I have now:

 files=$(find /home/mathias/Videos/movies/ -iname *.avi -type f -
 printf %P\n | grep ${cur} | sed s/\\([][\\(\\) ,\']\\)/\\1/
 g)

Got this to work:

 files=$(find /home/mathias/Videos/movies/ -iname *.avi -type f -
printf %P\n | grep ${cur} | while read file; do
printf %q $file
echo
done)

With the %q option to printf it no longer accepts a \n so I needed the
extra echo.

/Mathias


Re: Strange compgen behaviour

2009-09-25 Thread Andreas Schwab
Mathias Dahl mathias.d...@gmail.com writes:

 Got this to work:

  files=$(find /home/mathias/Videos/movies/ -iname *.avi -type f -
 printf %P\n | grep ${cur} | while read file; do
 printf %q $file
 echo
 done)

 With the %q option to printf it no longer accepts a \n so I needed the
 extra echo.

printf %q\n works fine here.

Also, grep ${cur} could probably be replaced by -path */${cur}*.

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
And now for something completely different.




Re: Bug in array populating does not respect quotes

2009-09-25 Thread David Martin
Thank you for all and sorry for the noise, you were right.

David.

On Thu, Sep 24, 2009 at 6:38 PM, Chris F.A. Johnson
ch...@cfajohnson.com wrote:
 On Thu, 24 Sep 2009, David Martin wrote:

 Configuration Information [Automatically generated, do not change]:
 Machine: x86_64
 OS: linux-gnu
 Compiler: gcc
 Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64'
 -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu'
 -DCONF_VENDOR='pc' -DLOCALEDI$
 uname output: Linux bristol 2.6.31 #10 SMP Thu Sep 10 17:59:29 CEST
 2009 x86_64 GNU/Linux
 Machine Type: x86_64-pc-linux-gnu

 Bash Version: 4.0
 Patch Level: 33 (debian bash-4.0-7)
 Release Status: release

 Description:
         When populating an array from a string in a variable does not
 handle quotes.

 Repeat-By:

 ~$ declare -a samplearray
 ~$ samplearray=( x y 'z k')
 ~$ echo ${samplearray[2]}
 z k
 ~$ samplestring=x y 'z k'
 ~$ samplearray=( $samplestring )

 eval samplearray=( $samplestring )

 ~$ echo ${samplearray[2]}
 'z

 --
   Chris F.A. Johnson, webmaster         http://woodbine-gerrard.com
   ===
   Author:
   Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)





Re: Strange compgen behaviour

2009-09-25 Thread Chet Ramey
Bernd Eggink wrote:
 Chet Ramey schrieb:
 Hm, compgen appears to behave strange if words contain whitespace. 

 Well, it splits the argument to -W on $IFS as documented.  What other
 strange behavior do you see? 
 
 For example, this:
 
 function _aha
 {
 local list=a b:c d:e f
 COMPREPLY=($(IFS=: compgen -W $list))
 }
 
 complete -F _aha aha
 
 Typing aha Tab cycles through 6 items a, b, c, d, e, f, whereas I
 would expect 3 items 'a b', 'c d', 'e f'. It looks like compgen splits
 the argument to -W on $IFS _and_ whitespace. Or am I missing something?

I don't think you're considering the interaction between compgen,
command substitution, and compound array assignment.

I'll use the assignment to `list' you used above for the explanation.

compgen performs word splitting using $IFS and then outputs the results,
one word per line:

$ IFS=: compgen -W $list
a b
c d
e f

Command substitution takes that, chops off the last newline, and, since
it's unquoted, performs word splitting using $IFS on the result:

$ recho $(IFS=: compgen -W $list)
argv[1] = a
argv[2] = b
argv[3] = c
argv[4] = d
argv[5] = e
argv[6] = f

If you want to preserve the embedded newlines, you have to quote the
expansion (but see below):

$ recho $(IFS=: compgen -W $list)
argv[1] = a b^Jc d^Je f

When performing compound array assignments, though, the words between
the parens undergo all the shell word expansions, including word splitting:

$ COMPREPLY=( $(IFS=: compgen -W $list) )
$ recho ${comprep...@]}
argv[1] = a
argv[2] = b
argv[3] = c
argv[4] = d
argv[5] = e
argv[6] = f

So you can split on just the embedded newlines by setting $IFS:

$ oifs=$IFS
$ IFS=$'\n' COMPREPLY=( $(IFS=: compgen -W $list) )
$ IFS=$oifs
$ recho ${comprep...@]}
argv[1] = a b
argv[2] = c d
argv[3] = e f

Remember to save and restore $IFS, though, since the assignment to it
preceding the assignment to COMPREPLY will persist.

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/




Re: Strange compgen behaviour

2009-09-25 Thread Bernd.Eggink

Chet Ramey schrieb:

Bernd Eggink wrote:

Chet Ramey schrieb:
Hm, compgen appears to behave strange if words contain whitespace. 

Well, it splits the argument to -W on $IFS as documented.  What other
strange behavior do you see? 

For example, this:

function _aha
{
local list=a b:c d:e f
COMPREPLY=($(IFS=: compgen -W $list))
}

complete -F _aha aha

Typing aha Tab cycles through 6 items a, b, c, d, e, f, whereas I
would expect 3 items 'a b', 'c d', 'e f'. It looks like compgen splits
the argument to -W on $IFS _and_ whitespace. Or am I missing something?


I don't think you're considering the interaction between compgen,
command substitution, and compound array assignment.

I'll use the assignment to `list' you used above for the explanation.

compgen performs word splitting using $IFS and then outputs the results,
one word per line:

$ IFS=: compgen -W $list
a b
c d
e f

Command substitution takes that, chops off the last newline, and, since
it's unquoted, performs word splitting using $IFS on the result:

$ recho $(IFS=: compgen -W $list)
argv[1] = a
argv[2] = b
argv[3] = c
argv[4] = d
argv[5] = e
argv[6] = f

If you want to preserve the embedded newlines, you have to quote the
expansion (but see below):

$ recho $(IFS=: compgen -W $list)
argv[1] = a b^Jc d^Je f

When performing compound array assignments, though, the words between
the parens undergo all the shell word expansions, including word splitting:

$ COMPREPLY=( $(IFS=: compgen -W $list) )
$ recho ${comprep...@]}
argv[1] = a
argv[2] = b
argv[3] = c
argv[4] = d
argv[5] = e
argv[6] = f

So you can split on just the embedded newlines by setting $IFS:

$ oifs=$IFS
$ IFS=$'\n' COMPREPLY=( $(IFS=: compgen -W $list) )
$ IFS=$oifs
$ recho ${comprep...@]}
argv[1] = a b
argv[2] = c d
argv[3] = e f

Remember to save and restore $IFS, though, since the assignment to it
preceding the assignment to COMPREPLY will persist.


Chet,

thanks for the clarification. It's actually quite obvious and I should 
have seen it myself.


Regards,
Bernd




Completion called within command substitution

2009-09-25 Thread Freddy Vulto
Configuration Information [Automatically generated, do not change]:
Machine: i486
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='i486'
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i486-pc-linux-gnu'
-DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash'
-DSHELL -DHAVE_CONFIG_H   -I.  -I../bash -I../bash/include
-I../bash/lib   -g -O2 -Wall
uname output: Linux myhost 2.6.26-2-686 #1 SMP Wed Aug 19 06:06:52 UTC
2009 i686 GNU/Linux
Machine Type: i486-pc-linux-gnu

Bash Version: 3.2
Patch Level: 39
Release Status: release

When completing command substitution:

$ a $(b cTAB

the command completion for `a' is invoked, whereas I'd expect the
command completion for `b' to be invoked.
I would expect the same behaviour as with process substitution, which
invokes the completion for `b':

$ a (b cTAB

Steps to reproduce:

1.  Create functions `_a' and `_b' to complete `a' and `b':

_a() { echo a; }
_b() { echo b; }
complete -F _a a
complete -F _b b

2.  Complete `b' within command substition:

$ a $(b cTAB  # This returns `a', where I'd expected `b'?

3.  Complete `b' within process substitution:

$ a (b cTAB  # This returns `b' all right.


Regards,

Freddy Vulto
http://fvue.nl