Umenu/Emdl

View: New views
6 Messages — Rating Filter:   Alert me  

Umenu/Emdl

by Grahame Blackwood :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Steve and all

I've installed umenu/emdl using the umenu-0.7.0-easyinstall.tgz and it
was an easy kick-off. Much easier than the previous method.

Getting the process of editing, compiling and transferring menus was a
bit more difficult.

The senario is like this:

I edit a main menu, say f.emdl, save it and exit Vim and return to the menu.
Then Compile it, giving the name f when the program asks for the menu name
and similarly giving the name f when doing the Transfer.

However, if the f.emdl has a sub-menu in the source called e, and I
edit that part of the f.emdl and save it as before, Compile it giving
the name f and then do the transfer, instead of giving the name f I had
to give the name fe to make the transfer work.

I don't know if this is expected behaviour but I can imagine that it
could save borking the whole menu if an error was made in the e part of
the source. However, I found it less than intuitive and it took me a
while to realise what was going on.

Having said that I'm making progress and I've got a few simple processes
installed in menus and they are effective.

One problem I found in using the menus was the lack of ability to pass a
parameter to a shell script called by a menu item (just date in the form of
YYMnth in my case). I solved that by adding a menu option to change the shell
script itself using vim. It would be nice though if umenu/emdl could pass
parameters to programs called by the menus.

Progress and I've learned quite a lot the last 24hrs or so.

So thanks and cheers

G


_______________________________________________
VimOutliner mailing list
VimOutliner@...
http://www.lists.vimoutliner.org/mailman/listinfo

Re: Umenu/Emdl

by David J Patrick-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Grahame Blackwood wrote:
> Hi Steve and all
>
> I've installed umenu/emdl using the umenu-0.7.0-easyinstall.tgz and it
> was an easy kick-off. Much easier than the previous method.

I took it for a quick test-drive, the "install" was trivial, the
function obvious. I have yet to make mu own menus, but it looks easy.
I will report back,
djp
_______________________________________________
VimOutliner mailing list
VimOutliner@...
http://www.lists.vimoutliner.org/mailman/listinfo

Re: Umenu/Emdl

by Steve Litt :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Monday 12 October 2009 15:07:37 Grahame Blackwood wrote:

> Hi Steve and all
>
> I've installed umenu/emdl using the umenu-0.7.0-easyinstall.tgz and it
> was an easy kick-off. Much easier than the previous method.
>
> Getting the process of editing, compiling and transferring menus was a
> bit more difficult.
>
> The senario is like this:
>
> I edit a main menu, say f.emdl, save it and exit Vim and return to the
> menu. Then Compile it, giving the name f when the program asks for the menu
> name and similarly giving the name f when doing the Transfer.
>
> However, if the f.emdl has a sub-menu in the source called e, and I
> edit that part of the f.emdl and save it as before, Compile it giving
> the name f and then do the transfer, instead of giving the name f I had
> to give the name fe to make the transfer work.
Hi Grahame,

I can't quite visualize what you mean, but I'm attaching a copy of the (very
much in progress) tutorial web page. That should answer this particular
question.

>
> I don't know if this is expected behaviour but I can imagine that it
> could save borking the whole menu if an error was made in the e part of
> the source. However, I found it less than intuitive and it took me a
> while to realise what was going on.
>
> Having said that I'm making progress and I've got a few simple processes
> installed in menus and they are effective.
>
> One problem I found in using the menus was the lack of ability to pass a
> parameter to a shell script called by a menu item (just date in the form of
> YYMnth in my case).
Here's how you'd do that:
Showdate
        param
                D: $HOME/showdatedir
                C: ./showdate.sh '07/11/21'

There's also the E: parameter which sets an environment variable.

> I solved that by adding a menu option to change the
> shell script itself using vim.

:-)

Self modifying code you maniac :-) I always wanted to write self modifying
code but never had the guts.

Another thing: If you want UMENU to query the user for an option, use Prompted
Argument Substitution. It looks like this:

param
        C: echo %1%Type string here please:%%

Whatever you typed will be used as an argument. I'll have that incorporated in
the tutorial by tomorrow.

> It would be nice though if umenu/emdl could
> pass parameters to programs called by the menus.
>
> Progress and I've learned quite a lot the last 24hrs or so.

Welcome! I'll try to get that tutorial to you as soon as prompted argument
substitution is in it. I think that will help a lot.

Steve

Steve Litt
Recession Relief Package
http://www.recession-relief.US
Twitter: http://www.twitter.com/stevelitt



UMENU Tutorial
UMENU Tutorial
Copyright 2009 by Steve Litt
Licensed GNU GPL version 2, see COPYING in main UMENU directory

Installing UMENU

Perform the following commands as a normal user:
cd
tar xzvf umenu-0.7.0-easyinstall.tgz
cd .umenu/program
./umenu.pl firstmenu
The preceding should bring up the UMENU pre-installed menu that looks something like the following:


Note that your .tgz file might have a slightly different name depending on exact distribution, and note that you could install UMENU below a different directory than your home directory, and rename the UMENU directory to something other than ./umenu, but the defaults are the easiest.

If the menu doesn't work, check that you're in the ~/.umenu/program directory, and you run the following command:
./umenu.pl firstmenu

Navigating the pre-installed menu

cd
cd ./umenu/program
./umenu.pl firstmenu
Assuming you installed as discussed in the Installing UMENU exercise, you'll be running the built in menu. Notice some menu choices are preceded by elipses and some aren't. The ones with elipses bring up submenus, while the ones without elipses run commands, so the two kinds of choices are called submenu choices and command choices. A third kind of choice is the kind that returns to the next highest level. Although it's not marked in a specific way, customarily it's called "Quit" or "Exit" so as to be obvious to the user.

Press t for test, and note that it displays a short poem. The T choice is a command choice. Press Enter to get back to the menu, and then press e. A submenu displays. Note that the submenu displays the string [firstmenue] to the right of the submenu's title, and remember that the initial menu displayed [firstmenu]. Each submenu has its menu letter appended onto the string representing the initial (top level) menu.

Now press q to return to the top level, which is one level up. Then press d for the docs submenu, and then h for the html docs menu. Note the string [firstmenudh] is to the right of the submenu's title. Press t for tutorial, and you'll see this tutorial appear in the Konqueror web browser. If you don't have Konqueror installed, nothing will happen.

Notice that konqueror runs, but UMENU is also fully functional and able to accept more input. UMENU has run Konqueror in the background. A UMENU choice can be configured to run its command in the background or run it in the foreground in which case the menu must wait for the foreground program to exit. If a Command Line Interface (CLI) program is run in the foreground, it simply takes over the terminal used by UMENU. If you want to see the output of the CLI program, there's a way to set a UMENU choice to wait for a keystroke before returning to the menu. That's how the Test choice off the top level was viewable -- the default setting for a choice would have caused the poem to flash briefly and then the menu to overwrite it.

One more thing. If you ever get stuck in a submenu with no way out (no Quit or Exit was programmed for the submenu), you can always get to the top level menu by pressing the equal sign (=).

Running a one-shot menu

In the preceding section, every time UMENU ran a process, when that process ended, UMENU took over again. That's great when you want a constant menu interface, but sometimes you want the menu to disappear after the menu runs the process. Think about it -- neither the Windows start menu, the KDE start menu nor the Gnome start menu stays active after you choose something from it. The start menu disappears. Sometimes you want that behavior. When you do, use the --terminate command line option to UMENU, like this:
./umenu --terminate firstmenu
Experiment with the preceding to get an idea what it does. Contemplate the fact that this behavior becomes much more practical when you configure your Linux desktop environment or window manager to run your menu system whenever you press Ctrl+9, which is a very easy key combo to hit.

Making Your Own Menu: Proof of Concept

First, run the built in menu by getting into UMENU's program directory and performing the following command:
./umenu.pl firstmenu
From the menu, press e for the edit/compile/transfer/run menu, and then e for edit. When asked the name of the EMDL file without extension, type hello and press the Enter key. An empty file called hello.emdl in the emdlfiles directory below the UMENU directory is now presented in an editor.

NOTE
The editor loaded is graphical gvim (graphical Vim). If you don't have graphical vim installed on your computer, install it for the sake of this tutorial. By the end of the tutorial you'll know how to change the EMDL file producing the built in menu to accommodate the editor or your choice, but for now just install graphical Vim.

If for some reason you can't, then edit the EMDL files with the editor of your choice from outside the menu system. Default location of EMDL file is the emdlfiles directory under your UMENU directory, which as installed in this tutorial is $HOME/.umenu.



Type the following, exactly:
hello:::My First Menu System
Terminal
param
C: xterm
^Quit
All indentation is done with tabs. the string "param" is indented by one tab, the string "C: xterm" is indented by two tabs. You must not use spaces.

The first line of an EMDL file is a special case. It must contain a short string (often just a single character) followed by three colons, followed by the desired title of the main menu.

The last line of an EMDL file must quit the main menu. It could be called "Quit", "Exit", "Leave" or anything else, but it must start with a carat.

The second line contains the name of a menu choice, in this case "Terminal". By default, the letter you press to invoke that choice will be the first uppercase character in the string -- in this case T. There are ways to override that default, which are discussed at http://www.troubleshooters.com/projects/emdl/index.htm, but for the sake of this tutorial, all menu letters will be the first uppercase letter of the choice string.

The third line is the word "param", indented one tab to show it's subservient to the choice string. Below "param" is a list of menu parameters, in this case only one: "C: xterm". Parameters always take the form of an upper case letter, a colon, a space, and a command or configuration option. The C stands for "command". So once the menu is compiled and transferred, pressing t will invoke the "Terminal" choice, which runs the xterm executable.

NOTE
This menu will work only if the xterm executable is on your computer. If it's not either install it (this is trivially easy with your package manager) or change the word "xterm" in the EMDL file to a terminal program you do have on your system.

Save the file. If you're using graphical Vim you can leave the file in the editor while performing the next steps, but if you have only command line Vim you must exit the file in order to return to the menu.

From the Edit, Compile and Run EMDL files Menu, press C to compile, and when asked for the EMDL file name without extension, type hello and press Enter. The menu compiles hello.emdl, and if all goes right it says "No errors" and "No warnings". If there are errors or warnings, check to see that you typed in the file exactly right, you used tabs instead of spaces for indentation, you remembered to save the file after editing it, and that when asked for the EMDL file name, you typed "hello" -- nothing less, nothing more.

Once you can get it to compile without warnings or errors, press T on the menu to transfer the .mnu files, moving them from a temp (.umenu/program/temp) to the area where they're used by UMENU (.umenu/menudir). The reason transfer isn't done automatically during compile is you don't want to lose or corrupt your current menu system if a compile errors out.

Now that you've edited, compiled, and transferred, run the menu by pressing the r key and type in "hello" when asked for the emdl. This runs the menu you just created, which looks like this:
Your "hello world" menu

Note first that the terminal's top bar in preceding image lists the directory as /d/at/perl/umenu_emdl/junkk/program. This is a special setup on my computer. When you do this tutorial as described, that directory should read /home/myuid/.umenu/program where "myuid" is your user name.

This menu has two choices, Terminal and Quit. Press the T key and xterm appears. Notice that once xterm appears, the menu becomes inactive -- you can't interact with it -- it's frozen. This is normal. Later this tutorial will walk you through running a program in the background, which enables you to use the menu after running a process like xterm.

Once you quit xterm, the menu becomes active again. Press q and the menu terminates. You'll notice a prompt for you to hit any key. This is a prompt from the built in menu. The "Run" choice of the built in menu has been configured so that the process it ran finishes, there's a prompt asking for a keystroke. This enables you to see how your new menu finished -- with an exit message. Once you press a key, you're back in the built in menu.

Do It Again With j.emdl

The identifier string for most menu systems is a single character, because it's easier to deal with. So redo the Making Your Own Menu: Proof of Concept exercise using j instead of hello, both when prompted for the EMDL filename, and on the first part of the first line of the EMDL file. You'll know you've succeeded when your new menu runs, and to the right of the main menu's title, instead of it saying [hello] it says [j]. If it still says [hello], check to make sure you've changed the first part of the first line of the EMDL file from hello to j, and that you use the letter j instead of the string hello on all prompts.

The letter j has been chosen because it's quick and easy to type over and over again during this tutorial. For the rest of this tutorial you'll use the j menu.

Put Xterm In the Background

From your built in menu, choose E to edit/compile/transfer/run and then e again to edit, typing in j when asked for the EMDL name. You're now editing j.emdl.

Put the string "B: 1" as a parameter under the param line. B stands for background. Theoritically the 1 stands for "on", but in fact if you have a B parameter with a value other than 1, at present the results are undefined. Use 1. The new file should look like this:

j:::My First Menu System
Terminal
param
C: xterm
B: 1
^Quit

Save in the editor, then in the menu compile, transfer and run. The new menu should be able to run as many copies of xterm as you want, with the menu still remaining active. This is how you run processes in the background.

Use Background Only For Graphical Apps

A program using the command line interface must have a terminal to run in. That terminal is the one UMENU is now running in. As a result, you do NOT want to run the new process in the background.

Running a CLI Program


As mentioned, a CLI (Command Line Interface) program needs a terminal to run in, and that terminal is typically whatever UMENU is already running in. In other words, the new program replaces UMENU in the terminal as long as the new program runs, and UMENU comes back afterwards.

For this exercise you'll run the Unix ls -l command in the current directory by adding an ls -l choice:
j:::My First Menu System
Terminal
param
C: xterm
B: 1
ls -l
param
C: ls -l
S: 1
^Quit

Notice the S: 1 for the ls -l choice. S means "stop". Instead of the default behavior of going right back to the menu that ran it, the menu prompts for a keystroke so the user can view the output of the program. In this case, pressing the letter l on this menu produces something like the following:
ls -l output

When you press a key, the menu appears again.

Sometimes you don't want processing to stop. For instance, if you're certain the process will work and don't want to view the output, don't put in the "S: 1". Likewise, if the command were ls -l | less, the less command stops the processing to show the output, so you don't need UMENU to also stop the processing.

Making a Submenu

So far you've programmed only command choices and quit choices. Command choices run a command via the operating system. Quit choices go up from a submenu to the menu that called it, or quit the main menu. Now you're going to program a third kind of choice, a submenu choice.

Submenu choices are easily identified because they contain a triple colon ":::" just like the first line. If any line other than the first (non-comment) line contains a triple colon, it's a menu choice.

Submenu choices contain choices of their own. A submenu's choices are under the submenu choice (the one with the triple colon), and are indented exactly one tab to the right of the submenu choice that owns them. To be functional, a submenu choice must have a quit choice, or else how would you ever leave the submenu?
NOTE
Sooner or later by accident you'll make a submenu without a quit choice. A submenu without a quit choice throws a warning during compilation, but perhaps you didn't see the warning. If you get into a quitless submenu, don't despair. You can press the equal key (=) to put you back at the main menu.

But try to always put a quit choice in every submenu.

Now that submenus have been explained, add a submenu called "Experimental" just above the main menu's quit command. The submenu contains a choice called "About" which prints a string and waits for a keystroke, and it contains a quit choice. The code for the new menu looks like this:

j:::My First Menu System
Terminal
param
C: xterm
B: 1
ls -l
param
C: ls -l
S: 1
Experimental:::Experimental Menu
About
param
C: echo A command spawned by experimental submenu
S: 1
^Quit
^Quit

The only magic in here is the "Experimental:::Experimental Menu" line. The text before the triple colon is the text of the choice in the current menu. The string after the triple colon is the title on the top of the generated submenu. When you compile, transfer and run the menu, it looks like this:
Main menuThis is the main menu. Notice that now a choice called "Experimental" appears. That's a submenu choice, as indicated by the ellipses preceding the choice. The string "Experimental" is the string BEFORE the triple colon.

The main menu's menu string is j, as shown in the [j] to the right of the menu title.

Now press e for "Experimental", and you're presented with the following submenu.

SubmenuAfter pressing e the submenu appears. The title, "Experimental Menu", is the part of the string after the triple colon.

The sub menu's menu string is je, as shown in the [je] to the right of the menu title.

Diagnostic Mode

Internally, UMENU works by constructing a shellscript executing the command with any other parameters in the param section, executing that shellscript, and then deleting that shellscript. When debugging, you need to see the script that UMENU makes, run it from the command prompt, and see where it errors out. If it's wrong, you need to find out how the menu choice's params produce it. But there's a problem -- UMENU erases the shellscript as soon as the command completes, or as soon as the command is placed in the background.

The solution is to use UMENU's --diag option. This option prevents the deletion of the shellscripts, so you can capture a shellscript, rename it to a simpler name, and debug the shellscript, and then change the choice's params accordingly.

So do this:
cd $HOME/.umenu/program
./umenu.pl --diag j
Within the menu, press the L key to have UMENU perform an ls -l command. After the command prints the directory's contents, press the q key to exit UMENU. Now, immediately, perform the following command:
ls -ltr temp/*
The preceding command prints a long directory of the contents of the temp directory under the current directory, sorting the contents by creation date and time. UMENU's temporary shellscripts are kept in that directory, at least as configured
echo "..... This is script ./temp/tempjL1255393755.sh ....."
ls -l
cd /d/at/perl/umenu_emdl/junkk/program

Specifying the Command Environment

With UMENU you can specify the current directory, the application search path so the command can be found, and any environment variables the command will use to tailor its performance. For instance, if you manually compile an application but aren't confident enough to do the make install, you can run it from its compilation binary directory by placing that directory at the head of the path, and set any environment variables the application uses, all the while setting the starting directory to the directory where data for that application uses.

This example won't be that

Using UMENU as a Start Menu

The menus you've run so far were persistent menus, meaning that after you ran whatever command needed to be run, the menu was once again ready to use. Persistent menus are great when you want to limit a user to a specific list of commands. However, the major use of menus at the operating system level is to give the user an easy to find route to all common commands, and then disappear.

The exact same EMDL file can produce either a persistent menu or a start menu. The difference is how umenu.pl is run. Do the following:
cd $HOME/.umenu/program
./umenu.pl --terminate j
The preceding runs the j.emdl as a start menu. Press the L key to do an ls -l command, asks you to press a key, but then puts you back in the operating system. It terminated after spawning a command, thereby acting as a start menu. Had you not used the --terminate option, it would have been a persistent menu.

Recap So Far

So far you've built a "hello world" menu whose choices are to run a GUI terminal emulator (xterm) and to quit. You explored running a command in the background with the "B: 1" param so that the menu stays functional while the executed command is still running. You explored the "S: 1" command useful when running a CLI command, so that the command's output isn't immediately overwritten by the menu, but instead waits for a keystroke before overwriting. You used an ls -l command to do that.

Last but not least you built a submenu using a line like this:
Experimental:::Experimental Menu
The string before the triple colon is the string that appears on the main menu, while the string after the triple colon is the string that is the title of the submenu. All of the submenu's choices, including its quit choice, are indented one tab to the right of the line with the triple colon. It wasn't mentioned so far, but submenus can be nested arbitrarily deeply.

You've now learned everything you need to know in creating a normal menu. There are a few special skills that haven't been covered, but if all you're doing is creating an ordinary menu system, you now know what you need in order to create it.

UMENU as an App or Front End

UMENU can be used as the user interface of an application, or as a front end to a few non-user-interface commands. For instance, you could take .ogg/.mp3 player mplayer, midi file player timidity, the Gnome volume control (gnome-volume-control), and a relatively simple app you write yourself to load, increment and decrement playlists, tie them together with UMENU, and have a halfway decent midi playlist player. Add in a picklist utility, a filepicker utility, and a signalling mechanism to stop a running song, and you have a quality CLI musical playlist application.

Often your needs are much less ambitios. Perhaps you have a command with a large and forgettable variety of options and arguments. Front ending that command with UMENU makes a user friendly, interactive version of the command, while still retaining a command line interface.

The next few sections of this document discuss the following app-building and front-ending techniques:
  • One choice, multiple commands
  • Prompted argument substitution
  • Environment variables
  • Persistent storage


One Choice, Multiple Commands




HELLO:::My First Menu System
Terminal





_______________________________________________
VimOutliner mailing list
VimOutliner@...
http://www.lists.vimoutliner.org/mailman/listinfo

Re: Umenu/Emdl

by Steve Litt :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Monday 12 October 2009 15:07:37 Grahame Blackwood wrote:
> Hi Steve and all
>
> I've installed umenu/emdl using the umenu-0.7.0-easyinstall.tgz and it
> was an easy kick-off. Much easier than the previous method.
>
> Getting the process of editing, compiling and transferring menus was a
> bit more difficult.

Hi Grahame (and any others messing with the new UMENU)

Place the attached tutorial.html in your $HOME/.umenu/docs/html directory, and
follow its exercises. It will probably take 2 hours and you'll be a UMENU guru
-- probably more UMENU knowledgeable than me.

By the way, here's how you set VimOutliner to recognize that an .emdl file is
an outline:

Within $HOME/.vim/ftdetect, create a file called my_vo_extensions with the
following content:

augroup filetypedetect
  au! BufRead,BufNewFile *.emdl         setfiletype vo_base
  au! BufRead,BufNewFile *.pho          setfiletype vo_base
augroup END

The preceding makes anything with extensions of .emdl or .pho outlines
editable as outlines by Vim. You probably don't have .pho files, so you can get
rid of that line.

When Vim starts, it runs every script in $HOME/.vim/ftdetect, so simply having
that file in the directory is enough to make .emdl files VO editable.

HTH

SteveT

Steve Litt
Recession Relief Package
http://www.recession-relief.US
Twitter: http://www.twitter.com/stevelitt



UMENU Tutorial
UMENU Tutorial
Copyright 2009 by Steve Litt
Licensed GNU GPL version 2, see COPYING in main UMENU directory

Installing UMENU

Perform the following commands as a normal user:
cd
tar xzvf umenu-0.7.0-easyinstall.tgz
cd .umenu/program
./umenu.pl firstmenu
The preceding should bring up the UMENU pre-installed menu that looks something like the following:


Note that your .tgz file might have a slightly different name depending on exact distribution, and note that you could install UMENU below a different directory than your home directory, and rename the UMENU directory to something other than ./umenu, but the defaults are the easiest.

If the menu doesn't work, check that you're in the ~/.umenu/program directory, and you run the following command:
./umenu.pl firstmenu

Navigating the pre-installed menu

cd
cd ./umenu/program
./umenu.pl firstmenu
Assuming you installed as discussed in the Installing UMENU exercise, you'll be running the built in menu. Notice some menu choices are preceded by elipses and some aren't. The ones with elipses bring up submenus, while the ones without elipses run commands, so the two kinds of choices are called submenu choices and command choices. A third kind of choice is the kind that returns to the next highest level. Although it's not marked in a specific way, customarily it's called "Quit" or "Exit" so as to be obvious to the user.

Press t for test, and note that it displays a short poem. The T choice is a command choice. Press Enter to get back to the menu, and then press e. A submenu displays. Note that the submenu displays the string [firstmenue] to the right of the submenu's title, and remember that the initial menu displayed [firstmenu]. Each submenu has its menu letter appended onto the string representing the initial (top level) menu.

Now press q to return to the top level, which is one level up. Then press d for the docs submenu, and then h for the html docs menu. Note the string [firstmenudh] is to the right of the submenu's title. Press t for tutorial, and you'll see this tutorial appear in the Konqueror web browser. If you don't have Konqueror installed, nothing will happen.

Notice that konqueror runs, but UMENU is also fully functional and able to accept more input. UMENU has run Konqueror in the background. A UMENU choice can be configured to run its command in the background or run it in the foreground in which case the menu must wait for the foreground program to exit. If a Command Line Interface (CLI) program is run in the foreground, it simply takes over the terminal used by UMENU. If you want to see the output of the CLI program, there's a way to set a UMENU choice to wait for a keystroke before returning to the menu. That's how the Test choice off the top level was viewable -- the default setting for a choice would have caused the poem to flash briefly and then the menu to overwrite it.

One more thing. If you ever get stuck in a submenu with no way out (no Quit or Exit was programmed for the submenu), you can always get to the top level menu by pressing the equal sign (=).

Running a one-shot menu

In the preceding section, every time UMENU ran a process, when that process ended, UMENU took over again. That's great when you want a constant menu interface, but sometimes you want the menu to disappear after the menu runs the process. Think about it -- neither the Windows start menu, the KDE start menu nor the Gnome start menu stays active after you choose something from it. The start menu disappears. Sometimes you want that behavior. When you do, use the --terminate command line option to UMENU, like this:
./umenu --terminate firstmenu
Experiment with the preceding to get an idea what it does. Contemplate the fact that this behavior becomes much more practical when you configure your Linux desktop environment or window manager to run your menu system whenever you press Ctrl+9, which is a very easy key combo to hit.

Making Your Own Menu: Proof of Concept

First, run the built in menu by getting into UMENU's program directory and performing the following command:
./umenu.pl firstmenu
From the menu, press e for the edit/compile/transfer/run menu, and then e for edit. When asked the name of the EMDL file without extension, type hello and press the Enter key. An empty file called hello.emdl in the emdlfiles directory below the UMENU directory is now presented in an editor.

NOTE
The editor loaded is graphical gvim (graphical Vim). If you don't have graphical vim installed on your computer, install it for the sake of this tutorial. By the end of the tutorial you'll know how to change the EMDL file producing the built in menu to accommodate the editor or your choice, but for now just install graphical Vim.

If for some reason you can't, then edit the EMDL files with the editor of your choice from outside the menu system. Default location of EMDL file is the emdlfiles directory under your UMENU directory, which as installed in this tutorial is $HOME/.umenu.



Type the following, exactly:
hello:::My First Menu System
Terminal
param
C: xterm
^Quit
All indentation is done with tabs. the string "param" is indented by one tab, the string "C: xterm" is indented by two tabs. You must not use spaces.

The first line of an EMDL file is a special case. It must contain a short string (often just a single character) followed by three colons, followed by the desired title of the main menu.

The last line of an EMDL file must quit the main menu. It could be called "Quit", "Exit", "Leave" or anything else, but it must start with a carat.

The second line contains the name of a menu choice, in this case "Terminal". By default, the letter you press to invoke that choice will be the first uppercase character in the string -- in this case T. There are ways to override that default, which are discussed at http://www.troubleshooters.com/projects/emdl/index.htm, but for the sake of this tutorial, all menu letters will be the first uppercase letter of the choice string.

The third line is the word "param", indented one tab to show it's subservient to the choice string. Below "param" is a list of menu parameters, in this case only one: "C: xterm". Parameters always take the form of an upper case letter, a colon, a space, and a command or configuration option. The C stands for "command". So once the menu is compiled and transferred, pressing t will invoke the "Terminal" choice, which runs the xterm executable.

NOTE
This menu will work only if the xterm executable is on your computer. If it's not either install it (this is trivially easy with your package manager) or change the word "xterm" in the EMDL file to a terminal program you do have on your system.

Save the file. If you're using graphical Vim you can leave the file in the editor while performing the next steps, but if you have only command line Vim you must exit the file in order to return to the menu.

From the Edit, Compile and Run EMDL files Menu, press C to compile, and when asked for the EMDL file name without extension, type hello and press Enter. The menu compiles hello.emdl, and if all goes right it says "No errors" and "No warnings". If there are errors or warnings, check to see that you typed in the file exactly right, you used tabs instead of spaces for indentation, you remembered to save the file after editing it, and that when asked for the EMDL file name, you typed "hello" -- nothing less, nothing more.

Once you can get it to compile without warnings or errors, press T on the menu to transfer the .mnu files, moving them from a temp (.umenu/program/temp) to the area where they're used by UMENU (.umenu/menudir). The reason transfer isn't done automatically during compile is you don't want to lose or corrupt your current menu system if a compile errors out.

Now that you've edited, compiled, and transferred, run the menu by pressing the r key and type in "hello" when asked for the emdl. This runs the menu you just created, which looks like this:
Your "hello world" menu

Note first that the terminal's top bar in preceding image lists the directory as /d/at/perl/umenu_emdl/junkk/program. This is a special setup on my computer. When you do this tutorial as described, that directory should read /home/myuid/.umenu/program where "myuid" is your user name.

This menu has two choices, Terminal and Quit. Press the T key and xterm appears. Notice that once xterm appears, the menu becomes inactive -- you can't interact with it -- it's frozen. This is normal. Later this tutorial will walk you through running a program in the background, which enables you to use the menu after running a process like xterm.

Once you quit xterm, the menu becomes active again. Press q and the menu terminates. You'll notice a prompt for you to hit any key. This is a prompt from the built in menu. The "Run" choice of the built in menu has been configured so that the process it ran finishes, there's a prompt asking for a keystroke. This enables you to see how your new menu finished -- with an exit message. Once you press a key, you're back in the built in menu.

Do It Again With j.emdl

The identifier string for most menu systems is a single character, because it's easier to deal with. So redo the Making Your Own Menu: Proof of Concept exercise using j instead of hello, both when prompted for the EMDL filename, and on the first part of the first line of the EMDL file. You'll know you've succeeded when your new menu runs, and to the right of the main menu's title, instead of it saying [hello] it says [j]. If it still says [hello], check to make sure you've changed the first part of the first line of the EMDL file from hello to j, and that you use the letter j instead of the string hello on all prompts.

The letter j has been chosen because it's quick and easy to type over and over again during this tutorial. For the rest of this tutorial you'll use the j menu.

Put Xterm In the Background

From your built in menu, choose E to edit/compile/transfer/run and then e again to edit, typing in j when asked for the EMDL name. You're now editing j.emdl.

Put the string "B: 1" as a parameter under the param line. B stands for background. Theoritically the 1 stands for "on", but in fact if you have a B parameter with a value other than 1, at present the results are undefined. Use 1. The new file should look like this:

j:::My First Menu System
Terminal
param
C: xterm
B: 1
^Quit

Save in the editor, then in the menu compile, transfer and run. The new menu should be able to run as many copies of xterm as you want, with the menu still remaining active. This is how you run processes in the background.

Use Background Only For Graphical Apps

A program using the command line interface must have a terminal to run in. That terminal is the one UMENU is now running in. As a result, you do NOT want to run the new process in the background.

Running a CLI Program


As mentioned, a CLI (Command Line Interface) program needs a terminal to run in, and that terminal is typically whatever UMENU is already running in. In other words, the new program replaces UMENU in the terminal as long as the new program runs, and UMENU comes back afterwards.

For this exercise you'll run the Unix ls -l command in the current directory by adding an ls -l choice:
j:::My First Menu System
Terminal
param
C: xterm
B: 1
ls -l
param
C: ls -l
S: 1
^Quit

Notice the S: 1 for the ls -l choice. S means "stop". Instead of the default behavior of going right back to the menu that ran it, the menu prompts for a keystroke so the user can view the output of the program. In this case, pressing the letter l on this menu produces something like the following:
ls -l output

When you press a key, the menu appears again.

Sometimes you don't want processing to stop. For instance, if you're certain the process will work and don't want to view the output, don't put in the "S: 1". Likewise, if the command were ls -l | less, the less command stops the processing to show the output, so you don't need UMENU to also stop the processing.

Making a Submenu

So far you've programmed only command choices and quit choices. Command choices run a command via the operating system. Quit choices go up from a submenu to the menu that called it, or quit the main menu. Now you're going to program a third kind of choice, a submenu choice.

Submenu choices are easily identified because they contain a triple colon ":::" just like the first line. If any line other than the first (non-comment) line contains a triple colon, it's a menu choice.

Submenu choices contain choices of their own. A submenu's choices are under the submenu choice (the one with the triple colon), and are indented exactly one tab to the right of the submenu choice that owns them. To be functional, a submenu choice must have a quit choice, or else how would you ever leave the submenu?
NOTE
Sooner or later by accident you'll make a submenu without a quit choice. A submenu without a quit choice throws a warning during compilation, but perhaps you didn't see the warning. If you get into a quitless submenu, don't despair. You can press the equal key (=) to put you back at the main menu.

But try to always put a quit choice in every submenu.

Now that submenus have been explained, add a submenu called "Experimental" just above the main menu's quit command. The submenu contains a choice called "About" which prints a string and waits for a keystroke, and it contains a quit choice. The code for the new menu looks like this:

j:::My First Menu System
Terminal
param
C: xterm
B: 1
ls -l
param
C: ls -l
S: 1
Experimental:::Experimental Menu
About
param
C: echo A command spawned by experimental submenu
S: 1
^Quit
^Quit

The only magic in here is the "Experimental:::Experimental Menu" line. The text before the triple colon is the text of the choice in the current menu. The string after the triple colon is the title on the top of the generated submenu. When you compile, transfer and run the menu, it looks like this:
Main menuThis is the main menu. Notice that now a choice called "Experimental" appears. That's a submenu choice, as indicated by the ellipses preceding the choice. The string "Experimental" is the string BEFORE the triple colon.

The main menu's menu string is j, as shown in the [j] to the right of the menu title.

Now press e for "Experimental", and you're presented with the following submenu.

SubmenuAfter pressing e the submenu appears. The title, "Experimental Menu", is the part of the string after the triple colon.

The sub menu's menu string is je, as shown in the [je] to the right of the menu title.

Diagnostic Mode

Internally, UMENU works by constructing a shellscript executing the command with any other parameters in the param section, executing that shellscript, and then deleting that shellscript. When debugging, you need to see the script that UMENU makes, run it from the command prompt, and see where it errors out. If it's wrong, you need to find out how the menu choice's params produce it. But there's a problem -- UMENU erases the shellscript as soon as the command completes, or as soon as the command is placed in the background.

The solution is to use UMENU's --diag option. This option prevents the deletion of the shellscripts, so you can capture a shellscript, rename it to a simpler name, and debug the shellscript, and then change the choice's params accordingly.

So do this:
cd $HOME/.umenu/program
./umenu.pl --diag j
Within the menu, press the L key to have UMENU perform an ls -l command. After the command prints the directory's contents, press the q key to exit UMENU. Now, immediately, perform the following command:
ls -ltr temp/*
The preceding command prints a long directory of the contents of the temp directory under the current directory, sorting the contents by creation date and time. UMENU's temporary shellscripts are kept in that directory, at least as configured. Pull up the bottom script in an editor or the less command and you'll see something that looks like the following:
echo "..... This is script ./temp/tempjL1255393755.sh ....."
ls -l
cd /d/at/perl/umenu_emdl/junkk/program

When UMENU doesn't work as expected, use of --diag suppresses shellscript deletion, giving you a diagnostic test point with which to work. Use it!

Specifying the Command Environment

With UMENU you can specify the current directory, the application search path so the command can be found, and any environment variables the command will use to tailor its performance.

For instance, if you manually compile an application but aren't confident enough to do the make install, you can run it from its compilation binary directory by placing that directory at the head of the path, and set any environment variables the application uses, all the while setting the starting directory to the directory where data for that application uses.

This example won't be that complicated. It will just create a couple environment variables and view them. Add the following code just above the bottom quit:
Create environment variables example
param
E: myfname=Steve
E: mylname=Litt
C: env | grep "^my"
S: 1
This menu choice creates environment variables $myfname and $mylname and then runs env to show that they've not only been created, but they're available to the command being run.

Here's an example of adding something to the path:
Prepend to path example
param
P: /d/at/perl:/d/at/ruby
C: echo $PATH
S: 1
This example prepends /d/at/perl and /d/at/ruby to the front of the path before running the command. In this way you can run special programs without permanently adding all sorts of junk to your path.

Here's an example of setting the current directory before running the command:
Directory setting example
param
D: /etc
C: less ./fstab
The current directory is set to /etc, and after that the command is run, pulling up the fstab file out of the local directory.

In all three cases, the environmental change is in effect when the command is run, but is rescinded once the command is finished. As you'll see later in this tutorial, one choice can run multiple commands. The changed environment is in effect for all the commands of that choice, but then is rescinded after they all terminate, or if the process runs in the background, they are not in effect when you go back to UMENU.

Here's a summary of the environment changing params:
PARAMWHAT IT DOES
D: directoryChanges to this directory before running the commands
P: colon separated directoriesPrepends the colon separted directories, which of course form a path themselves, to the current execution path ($PATH). Do not end the colon separated with a colon -- UMENU does that for you and it would be an error to have a double colon.
E: key=valueDefines an environment variable that is in effect when the commands run but not after. The key is the environment variable name, the value is the environment variable's value. You can have as many of these as you want -- one for each environment variable you need.

Using UMENU as a Start Menu

The menus you've run so far were persistent menus, meaning that after you ran whatever command needed to be run, the menu was once again ready to use. Persistent menus are great when you want to limit a user to a specific list of commands. However, the major use of menus at the operating system level is to give the user an easy to find route to all common commands, and then disappear.

The exact same EMDL file can produce either a persistent menu or a start menu. The difference is how umenu.pl is run. Do the following:
cd $HOME/.umenu/program
./umenu.pl --terminate j
The preceding runs the j.emdl as a start menu. Press the L key to do an ls -l command, asks you to press a key, but then puts you back in the operating system. It terminated after spawning a command, thereby acting as a start menu. Had you not used the --terminate option, it would have been a persistent menu.

Recap So Far

So far you've built a "hello world" menu whose choices are to run a GUI terminal emulator (xterm) and to quit. You explored running a command in the background with the "B: 1" param so that the menu stays functional while the executed command is still running. You explored the "S: 1" command useful when running a CLI command, so that the command's output isn't immediately overwritten by the menu, but instead waits for a keystroke before overwriting. You used an ls -l command to do that.

Last but not least you built a submenu using a line like this:
Experimental:::Experimental Menu
The string before the triple colon is the string that appears on the main menu, while the string after the triple colon is the string that is the title of the submenu. All of the submenu's choices, including its quit choice, are indented one tab to the right of the line with the triple colon. It wasn't mentioned so far, but submenus can be nested arbitrarily deeply.

You've now learned everything you need to know in creating a normal menu. There are a few special skills that haven't been covered, but if all you're doing is creating an ordinary menu system, you now know what you need in order to create it.

UMENU as an App or Front End

UMENU can be used as the user interface of an application, or as a front end to a few non-user-interface commands. For instance, you could take .ogg/.mp3 player mplayer, midi file player timidity, the Gnome volume control (gnome-volume-control), and a relatively simple app you write yourself to load, increment and decrement playlists, tie them together with UMENU, and have a halfway decent midi playlist player. Add in a picklist utility, a filepicker utility, and a signalling mechanism to stop a running song, and you have a quality CLI musical playlist application.

Often your needs are much less ambitios. Perhaps you have a command with a large and forgettable variety of options and arguments. Front ending that command with UMENU makes a user friendly, interactive version of the command, while still retaining a command line interface.

The next few sections of this document discuss the following app-building and front-ending techniques:
  • One choice, multiple commands
  • Environment variables
  • Prompted argument substitution
  • Persistent storage

One Choice, Multiple Commands (and Environment Variables)

View System Resources
param
C: tempfilename=$(mktemp);
C: echo This is file $tempfilename >> $tempfilename
C: echo *****CPU INFO***** >> $tempfilename;
C: cat /proc/cpuinfo >> $tempfilename;
C: echo >> $tempfilename;
C: echo *****MEM INFO***** >> $tempfilename;
C: cat /proc/meminfo >> $tempfilename;
C: less $tempfilename;
C: rm -f $tempfilename;
This choice works on any system with the /proc subsystem, in other words, almost any Linux system but not Unix or BSD. It runs nine commands in a row to put the info from /proc/cpuinfo and /proc/meminfo into a nice, readable file, and then once the file has been read and put away, it erases the file.

Notice that each command is ended with a semicolon (;). This is because when EMDL is converted to .mnu, all the commands are put on one line.

In the preceding, notice you set an environment variable at runtime (using the E param sets it at "compile time"), then used that environment variable as a filename, and ran several commands to create a file to view.

Prompted Argument Substitution

Consider the following choice to make a symlink. If you're anything like me, you can never remember which comes first, the original file or the new name you're giving the file. This is a perfect, although ultra simple, use for prompted argument substitution as follows:
Make symlink
param
C: ln -s %2%Name of original file, with path please%% %1%New name with path please:%%

In the preceding, the command's arguments are prompts started by %d% where d is a digit or letter, and ended by %%. UMENU then asks the user for each argument, and the user's answers are substituted for the prompts. The information requests are done in order of the digits between the first two percent signs. In other words, the order in which the user is asked does not have to be the order in which the arguments are sent to the command. You've just put a very nice, user friendly interface on an otherwise forgettable command. The command stops looking like an argument laden executable and starts looking like an application.

Place the "Make symlink" code in your UMENU, and make a symlink to an unimportant directory (please back up first), and notice the symlink is made.

If you remember, the built in menu asks you for the EMDL filename minus extension for editing, compiling, transferring and running. This is done with prompted argument substitution.

Persistent Storage

A real application requires persistent storage. UMENU cannot store information between one choice and another, or at least not in memory. But it sure can store it on disk.

So what we'll do is make a directory called .persist below your home directory containing key-value pairs where the key is a filename and the value is the contents of the file. In the

perSistent storage:::Persistent Storage Menu
Create persist directory
param
C: mkdir $HOME/.persist
set Browser executable
param
C: echo %1%Browser executable please:%% > $HOME/.persist/browser
set Editor executable
param
C: echo %1%Editor executable please:%% > $HOME/.persist/editor
bRouse UMENU tutorial
param
D: $HOME/.umenu/docs/html/
C: mybrowser=$(cat $HOME/.persist/browser);
C: $mybrowser tutorial.html
eDit junk.jnk
param
C: myeditor=$(cat $HOME/.persist/editor);
C: $myeditor $HOME/junk.jnk

param
^Quit

First create the .persist directory with the C choice. Then set the browser executable and editor executable with the B and E choices. Then, when you want, you can browse the UMENU tutorial or edit $HOME/junk.jnk without typing in the browser or editor executable name.

Sweeter still, this persists not only between menu choices, but between entirely different menu sessions.

Treating filename-filecontents as key-value pairs is probably the easiest way to keep persistent information, but it's by no means the only way. You could use config files, outlines, YAML, or anything else, or any combination.



_______________________________________________
VimOutliner mailing list
VimOutliner@...
http://www.lists.vimoutliner.org/mailman/listinfo

Parent Message unknown Re: Umenu/Emdl

by Grahame Blackwood :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tuesday 13 October 2009 21:05:23 you wrote:

> > Getting the process of editing, compiling and transferring menus was a
> > bit more difficult.
> >
> > The scenario is like this:
> >
> > I edit a main menu, say f.emdl, save it and exit Vim and return to the
> > menu. Then Compile it, giving the name f when the program asks for the
> > menu name and similarly giving the name f when doing the Transfer.
> >
> > However, if the f.emdl has a sub-menu in the source called e, and I
> > edit that part of the f.emdl and save it as before, Compile it giving
> > the name f and then do the transfer, instead of giving the name f I had
> > to give the name fe to make the transfer work.
>
> Hi Grahame,
>
> I can't quite visualize what you mean, but I'm attaching a copy of the
> (very much in progress) tutorial web page. That should answer this
> particular question.
>
Apologies for my inadequate explanation. However, I think I have the
process in my head now and I don't think it will cause me any real
problems from now on. I look forward to you tutorial web page. The link
at the bottom of you email looked like raw html when I aimed my browser
at it. Not good to read! So I'll wait a bit until it's ready.

> > One problem I found in using the menus was the lack of ability to pass a
> > parameter to a shell script called by a menu item (just date in the form
> > of YYMnth in my case).
>
> Here's how you'd do that:
> Showdate
>         param
>                 D: $HOME/showdatedir
>                 C: ./showdate.sh '07/11/21'
>
> There's also the E: parameter which sets an environment variable.
>
> > I solved that by adding a menu option to change the
> > shell script itself using vim.
> >
>
> Self modifying code you maniac :-) I always wanted to write self modifying
> code but never had the guts.
>
Er, not really self modifying code! I just edited the source of the
shell script to include a variable rather than use $1 as a parameter to
the shell script. I'll try your suggestions today.

> Another thing: If you want UMENU to query the user for an option, use
> Prompted Argument Substitution. It looks like this:
>
> param
>         C: echo %1%Type string here please:%%
>
> Whatever you typed will be used as an argument. I'll have that incorporated
> in the tutorial by tomorrow.

That's kind of what I was looking for originally but saw a reference in
the EMDL README.html that Prompted Argument Substitution wasn't possible
so didn't look much further. However, there are examples in the
firstmenu.emdl so I should have known.
>
> Welcome! I'll try to get that tutorial to you as soon as prompted argument
> substitution is in it. I think that will help a lot.

Yes, I'm looking forward to that as well as a more VO like UMENU/EMDL.

Cheers and many thanks for your efforts.

G




_______________________________________________
VimOutliner mailing list
VimOutliner@...
http://www.lists.vimoutliner.org/mailman/listinfo

Parent Message unknown Re: Umenu/Emdl

by Grahame Blackwood :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Steve and all

My comments interspersed:

On Wednesday 14 October 2009 18:25:04 you wrote:
> Place the attached tutorial.html in your $HOME/.umenu/docs/html directory,
> and follow its exercises. It will probably take 2 hours and you'll be a
> UMENU guru -- probably more UMENU knowledgeable than me.

> http://lists.vimoutliner.org/pipermail/vimoutliner/attachments/20091013/e94
>fc15e/tutorial.html

I still can't read this comfortably as it presents itself as raw html.

>
> By the way, here's how you set VimOutliner to recognize that an .emdl file
> is an outline:
>
> Within $HOME/.vim/ftdetect, create a file called my_vo_extensions with the
> following content:
>
> augroup filetypedetect
>   au! BufRead,BufNewFile *.emdl         setfiletype vo_base
>   au! BufRead,BufNewFile *.pho          setfiletype vo_base
> augroup END
>
> The preceding makes anything with extensions of .emdl or .pho outlines
> editable as outlines by Vim. You probably don't have .pho files, so you can
> get rid of that line.
>
> When Vim starts, it runs every script in $HOME/.vim/ftdetect, so simply
> having that file in the directory is enough to make .emdl files VO
> editable.

Absolutely love this. Menu files in glorious technicolor and VO
abilities as well! They are so much more readable and obvious in colour.
However, I couldn't get the my_vo_extensions file to work as you set out
above.

What brought success was to copy the line from your example:

  au! BufRead,BufNewFile *.emdl         setfiletype vo_base

directly into the vo_base.vim file.

I don't know how legitimate this is or why your example wouldn't work
for me as you set it out.

I don't know how legitimate this is or why your example wouldn't work
for me as you set it out.

In an earlier email you showed me the following example which works fine
and allows me to pass parameters to scripts:

Showdate
        param
                D: $HOME/showdatedir
                C: ./showdate.sh '07/11/21'

I haven't yet tried the E: parameter which sets an environment variable,
but I'll keep it in mind.

Thanks again for the guidance and your patience. Progress for me!

Cheers

G





_______________________________________________
VimOutliner mailing list
VimOutliner@...
http://www.lists.vimoutliner.org/mailman/listinfo