Subject: FVWM: Arithmetics?

From: "Felix E. Klee" <[email-masked]>
Date: Sun, 20 Apr 2003 21:02:11 +0200

Hi,

I want to do a lot of "realtime" (i.e. M4 is not an option) arithmetics in 
.fvwm2rc. Currently I'm using expressions like
    PipeRead `let "x=$[FVWM_A]*$[FVWM_B]"; printf "SetEnv
        FVWM_C $$x"`
This has two advantages:
1. It is not very readable
2. It depends on the shell I'm using

Are there any better ways for doing arithmetics in FVWM? Will arithmetics 
ever be built in?

Felix

-- 
To contact me personally don't reply but send email to 
  felix DOT klee AT inka DOT de
--
Visit the official FVWM web page at <URL: http://www.fvwm.org/>.
To unsubscribe from the list, send "unsubscribe fvwm" in the body of a
message to [email-masked].
To report problems, send mail to [email-masked].

---

From: Mikhael Goikhman <[email-masked]>
Date: Sun, 20 Apr 2003 19:35:21 +0000

> Are there any better ways for doing arithmetics in FVWM? Will arithmetics 

Use FvwmPerl in 2.5.x for arithmetics and string operations:

  FvwmPerl

  SendToModule FvwmPerl eval  $c = "AnimatedMove"; $n = 50;
  SendToModule FvwmPerl eval  cmd("Current $c " . ($n / 2) . " 10p")
  SendToModule FvwmPerl eval  $n /= 5; cmd("AnimatedMove $n 50")

This way you don't need environment variables or separate processes.

But read the man page first. And see the X output for your possible
perl errors.

FvwmPerl may also be used as a more powerful replacement for FvwmCpp and
FvwmM4 using its -p (--preprocess) flag.

Regards,
Mikhael.

---

From: "Felix E. Klee" <[email-masked]>
Date: Sun, 20 Apr 2003 22:30:16 +0200

I found a simple solution that makes arithmetics more readable, at least:

  DestroyFunc Let
  AddToFunc Let
  + I PipeRead `bash -c 'let "FVWM_LET_TMP=$1"; printf "SetEnv $0
  $$$$FVWM_LET_TMP"'`

That way I can easily write complicated arithmetic expressions, eg.

  Let FVWM_TMP "($[desk.n] >= $[FVWM_HDESKS]) ? -$[FVWM_HDESKS] : 0"

It also is independent of the shell "sh" since "bash" is specified 
explicitly.

What do you think of it? If you think it could be added to the FAQ, I'm 
willing to write the entry.

Felix

---

From: "Felix E. Klee" <[email-masked]>
Date: Sun, 20 Apr 2003 22:34:23 +0200

> Use FvwmPerl in 2.5.x for arithmetics and string operations:

Thanks, that's also a possibility.

> This way you don't need environment variables or separate processes.

Hm, don't you consider Perl a separate process? In addition, don't I need 
environment variables to interface with perl? 

Also, is there some reason to avoid environment variables? If I avoid name 
clashes by prefixing them all with eg. FVWM_ then I believe that shouldn't 
cause any trouble.

> FvwmM4 using its -p (--preprocess) flag.

To be honest, I don't like that preprocessing stuff. Some standard FVWM 
expressions do always collide with the preprocessor.

Felix

---

From: Mikhael Goikhman <[email-masked]>
Date: Mon, 21 Apr 2003 01:25:15 +0000

> environment variables to interface with perl? 

I mean that when you start one FvwmPerl process together with fvwm,
there are 0 forks per line. And when you invoke PipeRead (i.e. /bin/sh)
that then starts bash, printf and similar, there are 3 forks per line.

> clashes by prefixing them all with eg. FVWM_ then I believe that shouldn't 

If it is easier for you to build a program using environment variables
(or by creating temporarily files), just do it. But there is another way.

> expressions do always collide with the preprocessor.

This is not the case with "FvwmPerl -p", there are no such collisions.
Try it just for fun. :) Here are several random ideas for preprocessing:

# ---------------------------------------------------------------------

AddToFunc InitFunction
+ I Exec exec xterm -n %{ $USER eq "root" ? "superuser" : $USER }% -ls

%{
	$MAIN_FONT = "lucidasans-10";
	@apps = ([ 'netscape', 'Netscape' ], [ 'xterm', 'XTerm' ]);
	$number_of_mouse_buttons = `xmodmap -pp | cut -d' ' -f3` + 0;
	""  
}%

%ModuleConfig FvwmPager destroy
	SolidSeparators
	Font %{$MY_MAIN_FONT}%
	Colorset 0
	DeskTopScale 28
	MiniIcons
%End ModuleConfig FvwmPager

AddToMenu Apps Applications Title
%{
	$menu = "";
	foreach (@apps) {
		($prog, $name) = @$_;
		$menu .= "+ '%$prog%$name' Exec exec $prog\n"
	}
	$menu;
}%

AddToFunc StartXTermWithUniqueTitle
+ I Exec xterm -name xterm-%{++$i}% -ls

%{ $number_of_mouse_buttons < 4 ? "Nop" : "" }% Mouse 4 R A GotoDesk +1

# ---------------------------------------------------------------------

I think it is at least much more readable then your solution with bash
and dozen of environment variables.

Regards,
Mikhael.

---

From: "Felix E. Klee" <[email-masked]>
Date: Mon, 21 Apr 2003 12:04:59 +0200

On Monday 21 April 2003 03:25, Mikhael Goikhman wrote:
> > Hm, don't you consider Perl a separate process? In addition, don't I
> > need environment variables to interface with perl?
>

OK, here's a realization in Perl:
    DestroyFunc Let
    AddToFunc Let
    + I SendToModule FvwmPerl eval my $tmp = $1; command("SetEnv $0 $tmp");

Anyways, what's the disadvantage of creating other processes?

> > > FvwmPerl may also be used as a more powerful replacement for FvwmCpp
> > > and FvwmM4 using its -p (--preprocess) flag.
> >

Ok, I see that Perl code is always included between %{ and }%. This indeed 
makes this module much more appropriate for preprocessing than FvwmM4 and 
FvwmCPP. There, in addition to name clashes, one has to adapt quoting and 
this is extremely annoying.

> and dozen of environment variables.

What you showed is preprocessing. As said in my original post, what I'm 
after is realtime processing where I need several global variables anyways. 
Concerning readability: I'm not a Perler and for me the code isn't very 
readable at all. Many FVWM users probably prefer a solution where they can 
do simple arithmetics without knowing Perl.

Felix

---

From: Mikhael Goikhman <[email-masked]>
Date: Mon, 21 Apr 2003 12:17:27 +0000

> do simple arithmetics without knowing Perl.

Your original message was about the native support of arithmetics
(does this include scripting and string manipulation or just 2+2?).

Can you define what would be the desired (and still not conflicting)
syntax for you? I think that if you insist on using only what you know
(i.e. bash), there is no point to suggest you something else. :)
Then just stick to PipeRead and fvwm+shell escaping, it works ok.

By the way, most of the sh-like shells support $(( 1 > 2 ? 3 : 2 + 2 )).

Regards,
Mikhael.

---

From: "Felix E. Klee" <[email-masked]>
Date: Mon, 21 Apr 2003 17:57:27 +0200

On Monday 21 April 2003 14:17, Mikhael Goikhman wrote:
> > after is realtime processing where I need several global variables
> > anyways. Concerning readability: I'm not a Perler and for me the code
> > isn't very readable at all. Many FVWM users probably prefer a solution
> > where they can do simple arithmetics without knowing Perl.
>

Just 2+2, etc.. It's probably not neccessary to include native arithmetics 
since it can easily be done using 3rd party tools. But if there is a lot of 
demand I guess it might be easy to add a simple Let command (I'm sure there 
are several small C libraries around that allow the avaluation of simple C 
like arithmetic expressions). OTOH such a command can also be easily forged 
by using Perl or other tools, maybe an example should be added to the FAQ.

Felix

---

From: "Felix E. Klee" <[email-masked]>
Date: Mon, 21 Apr 2003 22:30:50 +0200

> Try it just for fun. :) Here are several random ideas for preprocessing:

Hm, I cannot get preprocessing to work. Here are the relevant lines from my 
.xinitrc:

    WINDOWMANAGER='/home/felix/local/bin/fvwm -cmd "Module FvwmPerl -p 
/home/felix/.fvwm2rc"'
    exec $WINDOWMANAGER 2> ~/local/var/log/windowmanager.log

But when starting FVWM I always get

    [FVWM][__execute_function]: <<ERROR>> No such command '%{'
    [FVWM][__execute_function]: <<ERROR>> No such command '}%'

BTW, could you add a section in the FvwmPerl man page that describes the 
configuratin neccessary for preprocessing and possibly more (sorry if it's 
already there, but I couldn't find it). This would simplify things a lot 
for beginners like me.

Another question: When I restart FVWM with Restart is .fvwm2rc then 
repreprocessed?

Felix

---

From: Mikhael Goikhman <[email-masked]>
Date: Mon, 21 Apr 2003 21:21:00 +0000

>     exec $WINDOWMANAGER 2> ~/local/var/log/windowmanager.log

This command looses the meaning of double quotes, so it becomes
-cmd '"Module'.

Try:

  eval $WINDOWMANAGER

No, "exec eval" does not work, contact your shell documentation for more.

I would suggest to name your configuration file differently, so you know
what type of file you have, say $HOME/.fvwm/config.ppp.

> already there, but I couldn't find it). This would simplify things a lot 

OK.

> Another question: When I restart FVWM with Restart is .fvwm2rc then 

With "Restart", yes.

Regards,
Mikhael.

---

From: "Felix E. Klee" <[email-masked]>
Date: Tue, 22 Apr 2003 01:33:08 +0200

On Monday 21 April 2003 23:21, Mikhael Goikhman wrote:
> > Hm, I cannot get preprocessing to work. Here are the relevant lines
> > from my .xinitrc:
> >

It does not seem to be possible to pass an environment variable as a command 
line to Bash's Exec command. One probably has to specify the arguments and 
the command name separately, eg. 
    exec $WM $WM_ARG1 $WM_ARG
works. However, I found this too cumbersome. So I wrote a little startup 
script "~./fvwm/startfvwm" and let this be called from .xinitrc.

Felix

---

From: Mikhael Goikhman <[email-masked]>
Date: Tue, 22 Apr 2003 03:14:23 +0000

On 21 Apr 2003 17:57:27 +0200, Felix E. Klee wrote:
> > > What you showed is preprocessing. As said in my original post, what
> > > I'm after is realtime processing where I need several global variables
> Just 2+2, etc.. It's probably not neccessary to include native
> arithmetics since it can easily be done using 3rd party tools. But if
> there is a lot of demand I guess it might be easy to add a simple Let
> command (I'm sure there are several small C libraries around that allow
> the avaluation of simple C like arithmetic expressions). OTOH such a
> command can also be easily forged by using Perl or other tools, maybe
> an example should be added to the FAQ.

Ok, here is a solution that makes your suggested function Let (that sets
environment variable) redundant. I call the function "." for compactness.
You may do 2+2 inside the command without temporary environment variables.

  AddToFunc .
  I SendToModule FvwmPerl preprocess -c -- $*

  . Exec exec xmessage %{2 + 2}%

  . GotoDesk 0 %{ $[desk.n] + 1 }%

  Next (MyWindow) . Move \
    %{($WIDTH - $[w.width]) / 2}%p %{($HEIGHT - $[w.height]) / 2}%p

The first example opens a "4" window, the second goes to the next desk.
The last example centers the given window, it should work in theory, but
it does not currently in cvs (should investigate why, probably a bug with
window contexts somewhere), here is a workaround for this using WindowId:

  Next (MyWindow) . WindowId $[w.id] Move \
    %{($WIDTH - $[w.width]) / 2}%p %{($HEIGHT - $[w.height]) / 2}%p

More examples that use some perl, not just arithmetics:

  . Exec exec xterm -name xterm-%{++$i}%
  . Exec exec %{ -x "/usr/bin/X11/aterm" ? "aterm" : "xterm" }% -sb

If this helps, I may put this in FAQ.

The function above only works in the current cvs, there was one problem.
If you want to use this with 2.5.2+ versions instead of cvs, then the "."
function above should be defined as the following instead:

  DestroyFunc .
  AddToFunc   .
  + I SendToModule FvwmPerl eval preprocess({ 'command' => 1 } , q<$*>)

Regards,
Mikhael.

---

From: Dominik Vogt <[email-masked]>
Date: Tue, 22 Apr 2003 10:02:55 +0200

> Are there any better ways for doing arithmetics in FVWM? Will arithmetics 

Just to put my oar in:  I'd like to centralise parsing of
numberic arguments everywhere in fvwm in the future.  This will
make it easy to add a <number>[{+-}<number>]... syntax without a
shell.

Bye

Dominik ^_^  ^_^

---

From: "Felix E. Klee" <[email-masked]>
Date: Tue, 22 Apr 2003 10:48:49 +0200

>   + I SendToModule FvwmPerl eval preprocess({ 'command' => 1 } , q<$*>)

That's very nice. There are some problems though:
o Your command conflicts with preprocessing. However, this can probably be
   solved by using different quote characters for preprocessing or by
   turning off preprocessing. After all, with "." I can move most stuff that
   needs to be preprocessed into init functions.
o The following configuration fails silently (i.e. FvwmPager doesn't start
   and there is no error message):

   AddToFunc .
   
   AddToFunc StartFunction
   + I Module FvwmPerl
   + I . Module FvwmPager 0 %{ 5 }%

If the above problems can be eliminated I think it is a very good idea to 
put this in the FAQ. Please add some example like the ones above. Also make 
sure that people know that they have to start the FvwmPerl module:

    AddToFunc StartFunction
    + I Module FvwmPerl

Felix

---

From: Mikhael Goikhman <[email-masked]>
Date: Tue, 22 Apr 2003 13:05:02 +0000

>    needs to be preprocessed into init functions.

Well, this function "." was only intended for non-preprocessed configs,
it adds an optional preprocessing to some given lines only.

If you preprocess the whole file, you don't need this function ".",
all lines are preprocessed statically anyway. But you may want this
function for dynamical preprocessing then, for example (syntax for cvs):

  DestroyFunc .
  AddToFunc   .
  + I SendToModule FvwmPerl preprocess -c --quote * -- $*

  Next (XTerm) . Exec xmessage *{ $[w.x] + $[w.y] }*

> sure that people know that they have to start the FvwmPerl module:

The man page suggest (I will make it more clear):

  ModuleSynchronous FvwmPerl

With simply "Module", the SentToModule command happens before it's ready.

Regards,
Mikhael.

---

From: "Felix E. Klee" <[email-masked]>
Date: Tue, 22 Apr 2003 15:22:24 +0200

On Tuesday 22 April 2003 15:05, Mikhael Goikhman wrote:
> > o Your command conflicts with preprocessing. However, this can probably
> > be solved by using different quote characters for preprocessing or by
> > turning off preprocessing. After all, with "." I can move most stuff
> > that needs to be preprocessed into init functions.
>

Sure that's what I'm using it for. And I consider doing all of the 
preprocessing in with "." because this makes it easier to define variables 
and reuse them later.

> > o The following configuration fails silently (i.e. FvwmPager doesn't
> > start and there is no error message):
> >
> >    AddToFunc .

What about this? Why doesn't it work?

Felix

---

From: Mikhael Goikhman <[email-masked]>
Date: Tue, 22 Apr 2003 14:49:29 +0000

On 22 Apr 2003 15:22:24 +0200, Felix E. Klee wrote:
> > >    + I SendToModule FvwmPerl eval preprocess({ 'command' => 1 }, q<$*>)
> > >
> > >    AddToFunc StartFunction
> > >    + I Module FvwmPerl

I thought I explained in the parent message why it should be:

  AddToFunc StartFunction
  + I ModuleSynchronous FvwmPerl
  + I . Module FvwmPager 0 %{ 5 }%

Or, maybe it does not work for you because you changed the quote char
using preprocess({ 'command' => 1, quote' => '*' }, q<$*>).

Regards,
Mikhael.

---

From: "Felix E. Klee" <[email-masked]>
Date: Tue, 22 Apr 2003 19:51:29 +0200

>   + I . Module FvwmPager 0 %{ 5 }%

Thanks, now it works.

> using preprocess({ 'command' => 1, quote' => '*' }, q<$*>).

No, I didn't redefine the quote character. I have disabled preprocessing of 
the whole configuration file. The problem is that variables defined during 
this kind of preprocessing aren't available later for use with the "." 
command. Therefore I moved all intitialization to init functions that are 
called from StartFunction. This works very good and AFAICS I don't need 
preprocessing of the whole config file anymore.

Some comments:
1. "." is very cool. Now that everything seems to work fine, please add it
   to the FAQ. And, as said before, include one or two simple examples that
   show that "." is usable with minimal Perl knowledge (eg. for adding 
   variables).
2. It seems that with "." it is only possible to embed one Perl command in  
   %{ ... }% at a time (i.e. not several Perl commands separated by ';').
   That should be made clear in the FAQ.

Felix

---

From: Mikhael Goikhman <[email-masked]>
Date: Tue, 22 Apr 2003 18:31:36 +0000

On 22 Apr 2003 19:51:29 +0200, Felix E. Klee wrote:
> command.

Actually it is possible to tell the FvwmPerl that preprocesses the whole
configuration to stay with fvwm, so all variables are still available.
Then use %{}% for statical preprocessing and *{}* for dynamical.

For example, create .fvwm2rc with only one line:

  ModuleSynchronous FvwmPerl --preprocess config.ppp --stay

But I should check up all synchronization issues with this.

> Therefore I moved all intitialization to init functions that are 

Later, when 2.5.7 is out.

>    That should be made clear in the FAQ.

What is the problem with 2 or 10 commands? Works fine for me (prints 3):

  . Exec exec xmessage %{ $count = 1; $count++; $count + 1 }%

Regards,
Mikhael.

---

From: "Felix E. Klee" <[email-masked]>
Date: Tue, 22 Apr 2003 21:59:54 +0200

One more question: Why does the following line procude a syntax error (I'm 
using 2.5.6 and the corresponding definition for ".")?
    . Echo %{ if ( 5 > 4 ) { return 5; } else { return 6; } }%

I also tried 
    SendToModule FvwmPerl eval if ( 5 > 4) { command("Echo 5"); } else {
    command("Echo 6"); }
and this works.

Felix

---

From: Mikhael Goikhman <[email-masked]>
Date: Tue, 22 Apr 2003 20:50:24 +0000

>     SendToModule FvwmPerl eval if ( 5 > 4) { command("Echo 5"); } else {

Both work for me. :)

Ah, yes, this is because you run old fvwm versions and use the q<$*>
syntax in the "." function definition. Replace it with q~$*~, then you
can use ">" but not "~" in your commands.

I really suggest to use run latest snapshot instead and use the syntax
for the "." function that has no such problems.

BTW, you may always omit "return" in perl, the result of the last
expression is used. This is the equivalent of your command:

  . Echo %{ 5 > 4 ? 5 : 6 }%

Regards,
Mikhael.

---

From: "Felix E. Klee" <[email-masked]>
Date: Thu, 24 Apr 2003 09:38:23 +0200

On Tuesday 22 April 2003 20:31, Mikhael Goikhman wrote:
> > 2. It seems that with "." it is only possible to embed one Perl command
> > in %{ ... }% at a time (i.e. not several Perl commands separated by
> > ';'). That should be made clear in the FAQ.
>

Hm, I cannot reprocude the problem I had anymore. I was assigning several 
variables in a statement similar to
    . Nop %{  $a = 3; $b = 5; }%
called from inside a function, and somehow the variables didn't get defined. 
However, now it works. Maybe I accidentally entered some syntactically 
incorrect Perl code.

Felix