Troubleshooters.Com® presents:

UMENU Text Based Menuing System (Major Version 2)

LINKS: Downloads Screenshots UMENU2 Apps

CONTENTS:

What Is UMENU?

UMENU is a text based menuing system. "Text based" means it works in a text environment, such as a console, a virtual terminal, or a GUI terminal emulator. It has no GUI (Graphical User Interface) code, making it much simpler than most programs. Here's a screenshot:

UMENU2 screenshot

Click here for more screenshots.

"Menuing system" means that at every stage of its use, UMENU presents the user with a list of choices, each identified by a unique letter. When the user types in one of those letters, the letter's corresponding choice is executed. Each choice can be of one of these three types:

So the phrase "UMENU is a text based menuing system" means that it's a system that continuously presents the user with choices executable by the press of a single keyboard key. Such choices can be to show a deeper menu, run a command on the computer, or return to the menu from which the user came. This user interface is entirely text based: There are no graphics. It can be used in a graphical user interface by running it within a Graphical terminal emulator, but still, UMENU only presents printable characters, and only reads keystrokes of printable letters.

Take another look at a UMENU screenshot:

UMENU screenshot

In the preceding screenshot, note the following:

UMENU Versions (and what's UMENU2?)

As of 10/27/2016, the current version of UMENU is 1.9.4. UMENU 1.9.1 through 1.9.4 and everything in the future that begins with either 1.9 or 2.0 through 2.8 is part of UMENU's major version 2. Major version 2 works just like Legacy UMENU for the user navigating its submenus and selecting choices, but it's a total rewrite for those constructing and designing menus.

REMEMBER:

As of 2016, the modern, maintained UMENU version is Major Version 2, sometimes shorthanded as UMENU2. Versions beginning with 1.9 are beta versions of Major Version 2, even though they begin with 1.

The original UMENU, now called Legacy UMENU was created as a Perl project in 1999, and maintained until 2015. It's now (as of 2016) deprecated and unsupported. All versions of Legacy UMENU had very low fractional version numbers. The 2011 Lua version, for instance, has version number 0.0.1. At one time or another Legacy UMENU was (re)written in Python, Ruby and Lua.

Legacy UMENU was an excellent quick and dirty front end for various commands and scripts. A command or a few commands with difficult to understand or remember command line options could be hosted by Legacy UMENU and transformed into a full application with an intuitive and discoverable user interface. This capability has been passed intact to modern UMENU (major version 2), and in fact since version 1.9.4 has been substantially enhanced for easier application construction.

Originally created to host small menuing systems, early in the 21st century Legacy UMENU acquired a co-project called EMDL (Easy Menu Definition Language), to convert an outline representation of a menu hierarchy to a .otl file for every menu in the hierarchy. With the addition of EMDL, Legacy UMENU easily accommodated huge menu hierarchies, but it became a deployment nightmare, even for me, its author. Menu hierarchy changes required changes to the EMDL file, followed by a complicated compilation to .otl files, which had to be in the correct directory to be in effect. It was a mess: It's probably why Legacy UMENU usership was somewhere around 100 people.

Modern major version 2 UMENU keeps its menu hierarchy in a directory tree directly useable by UMENU, with no compilation/copy step. This makes it much more deployable and maintainable. The menu hierarchy can reasonably be maintained by a file manager, and UMENU now also offers scripts newmenu.py and newitem.py These make configuration fairly quick and easy for the menu maintainer. More importantly, this hierarchy representation sets the stage for a future UMENU-centric configuration feature in which UMENU can be put in an "edit" mode so that selecting a choice enables the user to edit the hierarchy and command properties of that choice.

NOTE:

Obviously, there will be provisions to enable and disable the edit mode. This could be as simple as membership in a group with edit mode ability.

Why UMENU?

Why UMENU? What is it good for? Why can't I use my Window Manager menu, or dmenu, or mouse-foo from Gnome or Unity, or shellscripts?These are very good questions, and the answer to the immediately preceding question is a lot of times you should use those alternatives. UMENU assumes its true role in productivity only in situations where those alternatives create problems.

Any of the following circumstances suggests use of UMENU:

If anything on the preceding list rings a bell with you, install UMENU. It's a trivially easy install, and you (or the user or users you're helping) just might like it.

Installing UMENU doesn't mean you use it all the time. You can still use dmenu, your window manager's menu, or your desktop environment's mouse-foo any time you want. But when the user is in a situation where UMENU bestows superior advantage, it can be used. Personally, I start up programs using UMENU less than half the time:

  1. dmenu: 70%
  2. UMENU: 20%
  3. Command line: 9%
  4. Window mgr menu: 1%

I don't use UMENU often, but when I need it, it's a huge time saver. I use it a lot for tasks like the book fulfillment process, the courseware making process, for various internet tasks more complex than running a browser, and for backup tasks. For trivial tasks like running a browser, email client or terminal emulator, I use dmenu. UMENU is one more tool in my toolbox, kind of like getting a set of box wrenches even though you already have a set of socket wrenches. Use the best tool for the task.

UMENU Is About Productivity

UMENU is built from the ground up to ease and quicken your workflow. That's why it uses only letters easily accessible from the touch-typist's home position. That's why it responds instantly to a keypress, without waiting for you to also push the Enter key. That's why this software is so fast that there's no observable latency between your keypress and the display of the next menu or the start of the command you selected. The only observable latency comes from the programs you start: Not from UMENU itself.

Another way UMENU eases and speeds your workflow is by providing a memorable and discoverable route to commands you don't use often enough to know by heart. It saves looking at man pages, asking friends, and experimentation. If used by unsophisticated users who don't know how to use man pages, it makes the impossible possible, and frees others from baby-sitting newbies.

UMENU can be used as a bolt-on front end to tame one or a few related commands with difficult to remember command line options and arguments, converting it/them from an inscrutable executable to a logical, discoverable application. You can use this to write very quick and simple applications. Write one or more programs or shellscripts whose only user interface are their command line arguments. Lacking user interactions, these programs or shellscripts are usually trivial to write: They're all algorithm and data. For database connectivity you can use the psql (Postgres) or mysql (MySQL/MariaDB).

This doesn't mean you should use UMENU for every situation. If you're simply running a command with no arguments, and that command is on the path, the dmenu program is quicker and easier. I highly suggest you install both UMENU and dmenu. Dmenu requires no menu system construction, so every command you run with dmenu saves making a UMENU entry for that program. I suggest confining your use of UMENU to commands requiring arguments.

Be a Hero With UMENU

This isn't for everyone. If your employer's password guardians don't trust your judgement, or if they're just overly possessive of their authority, or if the powers that be would rather endure a huge business problem than temporarily put out a non-aesthetic and antique looking program to fix that business problem, you'll not be permitted to do this. But if you can, it's a way you can save the day and get a tickertape parade.

In some work situations you can use UMENU to build a functional prototype in record time. Write the program logic as a shellscript or Python or C or whatever, use psql or mysql or something like them for the database access, and use UMENU as the user interface. If you use Prompted Argument Substitution, be sure to sanitize user inputs. Freed from having to program the User Interface with PyQT or Rails or whatever, you can write pure logic and get it done quick, taking a few minutes at the end to bolt on UMENU as a user interface. Such prototypes not only save the day when the needed functionality will take too long to code, but serve as prototypes and user wish collection to the developers of the "real application". In some work situations, doing this is a good way to get a tickertape parade.

And when you're writing a program just for yourself, this technique can cut programming time in half or better.

UMENU Uses Lowercase

All letters used in UMENU are lowercase. All choice letters, all keys for key-value pairs, are entirely lowercase. It's currently undefined what would happen if you used an uppercase letter as a choice letter or in a key of a key-value pair. Use lowercase!

You might notice that UMENU displays the menu letter as uppercase to the user. This is just to achieve visibility, and UMENU will lowercase an uppercase choice letter. Soon enough the user will learn it's easier to type in lowercase.

This "lowercase only" rule has been implemented to give you less to remember as you configure the program and its menu structures.

Secret Keystrokes

As of version 1.9.4, UMENU has five secret keystrokes built in. The only one you really need to remember is the question mark, because as of 1.9.4, the question mark bestows a help screen with a list of all the secret keystrokes (sometimes called magic keystrokes) and their functionality. Here's a list:

Key
stroke
Functionality
? List all magic keys
; Refresh screen
= Go to top level
^ Go up one level
@ Show UMENU configuration

The equal sign (=) key instantly brings you all the way back up to the root menu. Use this to escape from a menu with no Quit/Return/eXit choice, or to instantly rise from several menus deep to the top menu: Often in order to quit.

The semicolon (;) key rereads the current menu and refreshes the screen. This is handy when the previously run command (usually a GUI program) spewed spurious text all over UMENU's text environment (this means you, Gnumeric), and also when you've modified the menu while UMENU was on the menu you modified.

The at-sign sign (@) key lists all of UMENU's major config variables in the same text session as UMENU is running in.

Menu Design

Menus are designed by people: They aren't thought up by computer algorithms. Menu designs are data input by people: Either the person who will be using the menu, a person or department overseeing the work of the user, a helpful person making a menu system to address a specific set of commands that need a more discoverable interface for newbie users, such as git, or a person creating a more memorable or more quickly typed interface for experts.

Menu designs are data. Data can reside in a relational database, a hierarchical database, a NoSQL database, a specially formatted text file such as XML, JSON or YAML, or in a representation by part of the system's directory and file structure.

A menu design could also be implemented as a pair of forms: One easy for a human to make, and another easy for the computer to process, with a compiler to turn the former into the latter. This two stage compiled menu system design format was used in Legacy UMENU, which turned out to be a deployment disaster. UMENU2 does not repeat that mistake.

UMENU now stores the menu structure in part of the system's directory and file structure. The entire structure of a menu system several menus wide and several menus deep is stored in a directory tree.

This makes the data lightning quick for UMENU to read and process, very easy for a human to modify with nothing more than a file manager or even a bare command prompt, and it results in very few software dependencies, as no parsers or database interfaces are needed. The following ASCII diagram represents a very simple, two level menu named "m" in which menu letter "p" pings 8.8.8.8, "b" presents the Browser Menu, "q" on both menus means "go back to higher level" or "Quit the program", depending where you are now, and f, c and e stand for Firefox, Chromium and Elinks respectively, and each directory called "data" contains data about the menu represented by its parent directory:

 m
 |---b
 |   |---c
 |   |   `---data
 |   |---data
 |   |---e
 |   |   `---data
 |   |---f
 |   |   `---data
 |   `---q
 |       `---data
 |---data
 |---p
 |   `---data
 `---q
     `---data

In the preceding diagram, top level "m" has choices "b", "p" and "q". Choice b runs a submenu, with choices "c", "e", "f" and "q". Every menu and every choice in the menu hierarchy contains a "data" directory, which contains data about the menu or command its parent directory represents. Typical data includes "choicetitle", "cmd", and "type" (m, c or r). Several other data pieces are either optional or specific to certain types (m, c or r). This is discussed in depth later.

Even though UMENU's menu structure can be edited in a filemanager or a bare command line, UMENU comes with two tools to double or triple the speed of adding new menus and choices

One, called newmenu.py, is used only to make a brand new root to a menu tree. The other, called newitem.py, questions the user about the new item's (and the item can be another menu) properties, and writes them in the directory tree. These two programs are plain text programs that write only printable characters and accept only printable characters and spaces. Lacking any method of moving up the screen, they repeatedly cycle through the properties until all properties are valid and the user accepts them. If this sounds like an interface last seen during the first Ronald Reagan administration, that's because it is. But the fact is, once you get used to it, it's faster, easier and clearer than most web or cellphone interfaces, meaning you can build your menus fast.

This section just gives a high level glimpse at the data structure of UMENU menus. Detailed specifications of the menu specification tree will be presented later in this document.

The Easy Installation Method

Unlike Legacy UMENU, major version 2 is extremely configurable. As distributed by Steve Litt, its defaults make it extremely easy to install the default way. Before installing UMENU, verify that you have no ~/.umenurc file and no ~/umenu2/ directory. If you have either of these, move them out of the way. Also, be sure your computer has Python 3 installed. Any Python 3: 3.1, 3.3, 3.4, whatever. Python 3 is very easy to install on any Linux distro, and works flawlessly side by side with Python 2.7. UMENU2 is new construction in 2016, it's written in the current Python, not the soon to be deprecated 2.7.

To find out whether Python 3 is installed, type the following command:

python3

If you get a "command not found" error, it's not. If you see a few lines of text followed by a >>> prompt, you're running Python. One of the preceding lines will tell you which exact Python version: If it's anything beginning with 3, it will run UMENU2. To exit Python, press Ctrl+D.

Now that Python 3 is installed and you have no ~/.umenurc and no ~/umenu2, you're ready to begin. The following instructions refer to umenu2_1_9_4.tgz and umenu2_1_9_4 directory. If your version number is different, just substitute it for 1_9_4. Here are your simple method installation instructions:

  1. Log in as your normal login, not root.
  2. cd
  3. tar xzvf umenu2_1_9_4.tgz
  4. mv umenu2_1_9_4 umenu2
  5. cd umenu2/prog
  6. ./umenu.py u

By following the preceding instructions, you not only installed UMENU, but you began navigating the u menu that comes with the UMENU2 distribution. Explore your menu. Look at the examples submenu. With a file manager, explore the directory tree headed by ~/umenu2/menu/u/. That tour is worth a thousand words.

Menu Structure Data Details

Consider this fact: Every choice you make on a menu interface is either a request to run a command, a request to run a submenu, or a request to move back up to the menu from which your current submenu was called. There are only three types of choices on a menu. Keep thinking about this, until you believe this and completely understand it.

In UMENU, these three types are represented as follows:

Activity Name Letter
run Command Command c
run (sub) Menu Menu m
Return to previous menu Return r

Now consider that a Menu type contains choices, but neither Return nor Command types contain other choices. Think about it until it's obvious.

The data tree for a modern UMENU menu system has two kinds of subdirectories:

  1. A single letter subdirectory representing a menu choice. That letter corresponds to the letter the user typed. Only Menu type subdirectories contain single letter directories, because only Menu types can contain choices.
  2. A subdirectory named data. Every single letter directory has one of these. The data subdirectory contains several files giving information about the choice indicated by its parent directory. Currently, the data subdirectory contains only files, no further subdirectories. Each file represents a key-value pair, with the filename being the key and the file's contents being the value.

As an example, the following ASCII diagram represents a very simple, two level menu named "m" in which menu letter "p" pings 8.8.8.8, "b" presents the Browser Menu, "q" on both menus means "go back to higher level" or "Quit the program", depending where you are now, and f, c and e stand for Firefox, Chromium and Elinks respectively, and each directory called "data" contains data about the menu represented by its parent directory:

 m
 |---b
 |   |---c
 |   |   `---data
 |   |---data
 |   |---e
 |   |   `---data
 |   |---f
 |   |   `---data
 |   `---q
 |       `---data
 |---data
 |---p
 |   `---data
 `---q
     `---data

Here are a few handy facts about these key-value pair files contained in data subdirectories:

Menu Construction

UMENU2 comes with two simple programs for construction: ./newmenu.py for creating a brand new root menu that's not below any other menu, and ./newitem.py for everything else. This section takes you through the construction of a very simple two layer menu system whose root menu has letter "z".

Making the Root Menu

To make the root menu, just run ./newmenu.py with the argument being the root menu's letter. Once you run the program, there's no user interaction, it just creates the asked for menu. The following is an example session for ./newmenu.py:

[slitt@mydesk ~]$ cd ~/umenu2/prog
[slitt@mydesk prog]$ ./newmenu.py z
You chose to create menu z.

New menu z is complete at /home/slitt/umenu2/menu/z

[slitt@mydesk prog]$ 

Now run the following command:

[slitt@mydesk prog]$ ./umenu.py z

UMENU now presents you with menu "z" which looks like the following:

Z menu immediately after creation

In the preceding, notice that the "z" menu's Quit choice is already made for you. Right now ./newmenu.py is the only program that pre-populates a Return type choice, but this ability might be added to ./newitem.py in later UMENU2 versions.

Adding Choices

The remainder of the menu construction consists of adding choices to existing menus, and is accomplished with ./newitem.py. Let's fill out the remainder of the "z" menu with a "p" choice to ping 8.8.8.8, and a "b" choice for the browser menu. The following is what the session to add the "p" choice looks like:

[slitt@mydesk prog]$ ./newitem.py z

Menu string "z", (Main Menu) 
contains the following directories:

q
data

Input menu letter of choice you want to create=>p
You chose p.
New item's type is either m (menu), c (command), or r (return).
Input new item's type (m, c or r)=>c

Input |bkground| please [f](t or f), =>>

Input |choicetitle| please [^^^], (required)=>Ping 8.8.8.8

Input |cmd| please [^^^], (required)=>ping -c 3 8.8.8.8

Input |dir| please [], ^^^ for none=>

Input |env| please [], ^^^ for none=>


Input |path| please [], ^^^ for none=>


Input |stop| please [f](t or f), =>t

Done inputting data for this item (y or n)?=>y
[slitt@mydesk prog]$

A couple interesting points. First, the user inputted legal values on every prompt, or else instead of receiving the "Done inputting data" prompt the program would have circled around each prompt again, until it had a legal set of values. Second, whatever is between the square brackets in the prompt is what the value will be if the user simply presses Enter. These values could have been read from disks if this item has already been input, they could be program defaults if the item is brand new, or they could be what the user input last time if the user is cycling around the prompts again. This ability to simply press Enter to match the most likely candidate makes data entry much quicker.

Did you notice that the "stop" property was set to "t" (True) instead of the default "f"? This is so that at the termination of the ping -c 3 8.8.8.8 command, instead of overwriting the command output with the menu, it prompts the user to press Enter when he's done, and only then does it re-present the menu.

Now let's add the Browser Menu as a choice on the "z" menu:

[slitt@mydesk prog]$ ./newitem.py z

Menu string "z", (Main Menu) 
contains the following directories:

p
q
data

Input menu letter of choice you want to create=>b
You chose b.
New item's type is either m (menu), c (command), or r (return).
Input new item's type (m, c or r)=>m


Input |choicetitle| please [^^^], (required)=>Browsers




Input |menutitle| please [^^^], (required)=>Browser Menu


Input |sort| please [-q], ^^^ for none=>


Done inputting data for this item (y or n)?=>y
[slitt@mydesk prog]$

In the preceding you notice right away that the initial list of directories includes the "p" menu item you input before, and you see that it asks different questions this time because its menu type is "m" instead of "c". If you look at menu "z" now, it is complete with its "b" and "p" choices, as shown following:

Z menu immediately after creation

Completing the Browser Menu

At this point, by including "b" (Browsers) on the main menu, you've also created an empty Browser Menu with letterstring "zb". It has no choices, including no choice of type "Return", meaning if you get there, the only way to get out is to press the equal sign (=) key to move all the way to the root menu. The next step is to populate the empty Browser Menu. Check out the next three ./newitem.py sessions reproduced on this page, staring with the following session, which adds the "f" choice to the Browser Menu...

[slitt@mydesk prog]$./newitem.py zb

Menu string "zb", (Browser Menu) 
contains the following directories:

data

Input menu letter of choice you want to create=>f
You chose f.
New item's type is either m (menu), c (command), or r (return).
Input new item's type (m, c or r)=>c

Input |bkground| please [f](t or f), =>t

Input |choicetitle| please [^^^], (required)=>Firefox

Input |cmd| please [^^^], (required)=>firefox

Input |dir| please [], ^^^ for none=>

Input |env| please [], ^^^ for none=>


Input |path| please [], ^^^ for none=>


Input |stop| please [f](t or f), =>

Done inputting data for this item (y or n)?=>y
[slitt@mydesk prog]$ 

The preceding session created the choice to run Firefox. Notable is the fact that you set bkground to "t", because you want GUI program Firefox to run in the background, independent of UMENU2. GUI programs are generally run with background set to "t".

Note that the preceding ./newitem.py session, and the following one, and in fact all ./newitem.py sessions are invoked with the letterstring of the existing menu to which you want to add choices. The choices you add are declared within the user interface of ./newitem.py.

The following session adds the "k" choice, which runs Elinks in the same terminal as UMENU2 is running. The Elinks choice is named "k" just to show the fact that the menu letter is completely independent of the choice title, although typically, for clarity, you'd make the menu letter a letter in the choice title, and would capitalize that letter in the choce title. But this action would be for humans, not for UMENU2.

[slitt@mydesk prog]$ ./newitem.py zb

Menu string "zb", (Browser Menu) 
contains the following directories:

f
data

Input menu letter of choice you want to create=>k
You chose k.
New item's type is either m (menu), c (command), or r (return).
Input new item's type (m, c or r)=>c

Input |bkground| please [f](t or f), =>

Input |choicetitle| please [^^^], (required)=>Elinks

Input |cmd| please [^^^], (required)=>elinks

Input |dir| please [], ^^^ for none=>

Input |env| please [], ^^^ for none=>


Input |path| please [], ^^^ for none=>


Input |stop| please [f](t or f), =>

Done inputting data for this item (y or n)?=>y
[slitt@mydesk prog]$

Notable in the preceding is that the "stop" property is not set to "t", even though most text interface programs run by UMENU2 are designated as "stop" being "y". The reason it's not this way in the preceding is that the elinks program requires the user to press Enter after he's chosen to quit, so setting "stop" to "t" would redundantly force the user to hit Enter yet again.

The final session installs the Quit choice, which of course is type Return, on the Browser Menu:

[slitt@mydesk prog]$ ./newitem.py zb

Menu string "zb", (Browser Menu) 
contains the following directories:

k
f
data

Input menu letter of choice you want to create=>q
You chose q.
New item's type is either m (menu), c (command), or r (return).
Input new item's type (m, c or r)=>r


Input |choicetitle| please [], (required)=>Quit








Done inputting data for this item (y or n)?=>y
[slitt@mydesk prog]$

See how little input was required of the user in the preceding session. This is typical of choices of type Return. After performing the preceding menu construction, the Browser Menu looks like the following:

Screenshot of completed Browser Menu

How Item Sorting Works

Item ordering could have been done a zillion way. Items could have been automatically sorted alphabetically, either by "choicetitle" or by menu latter. Return types could have automatically been placed at the bottom. All menu types could have been grouped and placed either above or below the command types. Such automatic sortings would have failed, however, because there are many valid reasons to have the menu designer hand-sort the items.

When it comes to hand-specifying the sort, there are three basic approaches:

Because UMENU2's data is kept in a directory, sorting them by order input is impossible, unless you sort on creation time, and that's extremely ugly and fragile. So we're left with including the sort in the menu, or including it in each of its choices.

Putting the sort criteria in each choice is quite doable, but the algorithm for turning the per-choice data into a sort is complex to begin with, made much more complex by the need to accommodate user error (infinite looping afters, for instance). Plus doing it in each item would have required a lot of thought and typing by the person inputting the menu data. When you subtract out the bad alternatives, the last alternative standing is storing the sort criteria in the menu, and this turns out to be a simple algorithm and a very quick and simple task for the person inputting the menu data.

On most menus, you want certain things at the top, certain things at the bottom, and often you don't care about the order of the things in the middle, as long as they're determinate so the user can get used to them. So in the sort string, which is the value of the sort file inside the data directory for the menu, you have a left part, a dash, and a right part.

The left part lists the letters of the choices at the top, in order, with the leftmost one at the very top of the menu, and the next-to-leftmost one just below it on the menu. Proceed left to right corresponding with top down until you hit the dash.

The dash represents all the letters not named in the sort file at all: These appear, in alpha order, below the choice represented by the letter just to the left of the dash. So, if every choice's letter were enumerated either before or after the dash, the dash would represent nothing, and the sort order would be completely specified by the sort file. However, this happens seldom. In fact, the most common sort file contents is "-q" which means "Put Quit at the bottom, alpha sort everything else".

The letters after the dash represent choices that go on the bottom, with the rightmost letter going on the bottom fo the menu, and the one just to the left of that going just above it on the menu, etc.

If there's a sort file, it must contain a dash. Everything else is optional: A string of "-" would simply alpha-sort all choices. The most common sort is "-q" which means "send q (Quit) to the bottom, and alpha sort the rest. But this method of sorting gives you the ability to sort any way that's needed. For instance, "hg-ba" would sort your choices as "h", "g", "c", "d", "e", "f", "b", and "a". "-hgfedcba" would sort as "h", "g", "f", "e", "d", "c", "b", and "a".

The algorithm is pretty robust. Letters in the sort file that aren't letters of actual choices of the menu just get ignored. With version 1.9.1, the effect of having a legitimate letter twice in the sort file contents is undefined, but later versions will treat it determinately.

So that's it: That's how to sort choices in UMENU2.

Menu Construction Productivity Tips

A menu system can be substantial. A menu system with five menu choices on each menu, for five levels, would lead to over 3000 choices. Regardless of tools, that would take a long time to do.

The first thing to understand is what to run from UMENU2, and what not to. If you want to run Firefox or an email client or some other program not requiring arguments, and not caring what directory it's run from, run that from dmenu. Likewise, if your running of a command is so complex that it involves branching and looping, build a shellscript around it and call that shellscript from dmenu. Generally speaking, if you need to put loops and branches in a UMENU2 choice's cmd file, you should write a shellscript to spawn that command. Save UMENU2 for fairly complex command structures that can benefit from an intuitive name. By limiting what you run from UMENU2, you'll greatly shrink your menu tree.

The fastest way to use ./newitem.py is from the command line, using the up-arrow to run the same command over and over again, filling in all choices on a given menu before going on. You'll be surprised how quickly it goes. When you're done with one menu, you go to a sibling menu or a submenu and do that whole thing.

You can change an existing choice with ./newitem.py as long as the choice's type is not changed. If the choice's type needs to be changed, you're probably better off deleting the choice and rerunning ./newitem.py.

All that ./newitem.py can do is to add and change choices. It can't delete choices, it can't rearrange the menu, it can't prune and graft. For these activities, what you want is a file manager. The Rox Filer file manager is excellent for this, always assuming you use drag and drop instead of cut and paste (Rox Filer's horrible at cut and paste). When you drop, Rox Filer gives you the choice of moving, copying, or a couple kinds of linking. Make sure to pick the right one.

Which brings up another point: Your menu hierarchy is your personal data, so back up often, in a way you can restore. How often? I'd say every 10 minutes when you're heavily changing it, especially with moves or deletions. You might want to use git. My testing suggests that a .git directory within a root menu's directory doesn't in any way compromise UMENU2 functionality.

When adding lots of items, you can speed things up and make things clearer by running UMENU on the menu you're adding to. Each time you add, press semicolon to refresh, and make sure it's added correctly.

Possible Future Features

Here are some possible future features:

Menu as checklist

Some future UMENU version will incorporate a version where one choice on a menu is marked as the "current" choice, and pressing the Enter key executes the current choice. After the current choice is executed, the "current" choice moves down to the next choice.

This requires three new abilities:

  1. Ability to mark the current choice
  2. Ability to track and increment the current choice
  3. Ability to respond to the Enter key by performing the current choice

#1 and #3 are easy. #2, not so much. Another challenge is preventing accidental runs by pressing the Enter key. Perhaps F10 would be a better key than Enter.

Integrated menu maintenance

Through use of a special key, UMENU2 could enter an Edit mode, wherein you could add/change/delete choices without leaving UMENU2. The advantage would be more "user friendly". The disadvantage would be a more complex software set. But not that much more complex, as the current umenu.py plus ./newitem.py already contain most of the necessary code.

Unlike most of the other features discussed here, this would involve big changes to many different parts of UMENU2, so if it gets implemented at all, will probably be implemented later than most other features.

Query User For Environment Variables To Be Used In Submenus

Right now the menu designer can define environment variables and their values, but it can't be done by the user in realtime. This might be useful, although it could also be a security problem.

Through use of a special key, UMENU2 could enter an Edit mode, wherein you could add/change/delete choices without leaving UMENU2. The advantage would be more "user friendly". The disadvantage would be a more complex software set. But not that much more complex, as the current umenu.py plus ./newitem.py already contain most of the necessary code.

Unlike most of the other features discussed here, this would involve big changes to many different parts of UMENU2, so if it gets implemented at all, will probably be implemented later than most other features.

Gui version

What can I say. Some people like GUI and the whole mouse thing. Not my cup of tea, but some people love it.

Making a GUI version of UMENU wouldn't be at all difficult. The menu config directory structure is already there, as are all the mechanisms for encapsulating menu data, creating command runner shellscripts, and ordering the choices. Even built in starting with the now deprecated 1.9.1 are icons.

Maybe when the rest of UMENU2 is incorporated, stable and documented, I'll write the GUI version. Or perhaps somebody else will do it.