secretGeek / ok-bash

.ok folder profiles for bash
MIT License
89 stars 6 forks source link

Allow named commands, not just numbered! #24

Closed secretGeek closed 4 years ago

secretGeek commented 4 years ago

Comparing .ok to npm "scripts" and make files:

I much prefer .ok, or even using them all together, but:

I do like the way npm run scripts and make files both give you a useful way to make "project specific commands" with a name, e.g.

make build
npm run build

...in both cases "build" is a command that has been defined in a local file, and is project specific. It will run a larger command that would've been harder to type...

Meanwhile ".ok" does the same but you only use a number.

Imagine you had an ".ok" file like this:

# Project activities
npm run ng serve -o # serve the code

Today, the output of typing "ok" would be something like this:

# Project activities
1. npm run ng serve -o # serve the code

And to 'serve the code' you would type "ok 1"

Producing an output like this:

$ ok 1
$ npm run ng serve -o # serve the code
....running the code...

you know all that. Here's the new idea:

Since we (more or less kind of) control the ".ok" file format.. what if we had a special convention, that says:

Any line starting with a verb with no spaces, followed by a colon... is defining a "verb" (a command). Everything after the colon is the command.

e.g. if ".ok" contained this:

# Project activities
serve: npm run ng serve -o
& clean.sh

then the output of "ok" would be:

# Project activities
serve: npm run ng serve -o
1: & clean.sh

And then to run that command you could type:

ok serve

(or ok 1 to run the next command.)

There would be no way to use a number to run the first command. It's pure command.

Numbers would still work exactly the same: Any line that doesn't start with a comment symbol is a numbered command.

Only slight change with number is the way they're displayed when you type just "ok" by itself.

Instead of "1. " (one dot space) it would be "1: " (one colon space)

...because then it would be consistent with the way command/verbs are displayed.

Basically:

serve. npm run ng serve -o
1. & clean.sh

looks a bit silly because that dot after serve is grammatically confusing, so the colon after numbers would be clearer/consistent.

The rules between ok-bash and ok-ps would be slightly different around case sensitivity of commands, as Powershell is not case-sensitive. Verb names should start with a letter, then allow [A-Za-z0-9-] (all letters, digits and hyphen) but no other character, and no leading or trailing space.

It would be good to have a uniform approach on what to do if they enter a command that does not match. Some scenarios:

cat .ok
build: build.sh
blast: rm *

if they type ok buil...

it is unambiguous what they mean.... should it be treated as build? I think yes because brevity is good in the land of ok

if they type ok b...

...it is ambiguous what they mean.... do we tell them no command found and just list all the availables? seems safe.

There would be some reserved words that cannot be used as commands, e.g. list

I know you have a lot more ideas on this and have done some research (@doekman) so i'll leave it you to respond, or I can paste in some of your research after a few days)

doekman commented 4 years ago

I like the idea of named .ok lines, but I think nouns and other type of words also should be allowed. If we call it named lines we could call the current lines anonymous lines, akin to functions in javascript and other languages. This way pronouns, verbs and adjectives also can be used (along with imaginary names).

If you run ok in a folder with this ok-file in it:

# This line is a comment (a heading-comment in ok-bash)
echo "This is a numbered command"
target: echo "This is a named target"
target: echo "This is a numbered (anonymous) command"
list: echo "This is a anonymous command"

it will display (reasons why in the comments):

# This line is a comment (a heading-comment in ok-bash)
1: echo "This is a numbered command"
target: echo "This is a named target"
2: echo "This is a numbered (anonymous) command" #...because target already exists in a previous line
3: echo "This is a anonymous command" #...because list is an existing ok-command

With the --verbose option, ok could write a warning to the stderr if a named line is shown as a numbered line.

Grammar: I think targets only contain letters, digits, underscore and dash, with a length of at least one, always start with a letter or a underscore (starting with number of dash leads to command-line argument problems). I think only ASCII letters, and case-sensitive (at least for ok-bash). I guess whitespace around the name is allowed, but not part of the name.

Regex (the first and only capture group is the name): ^[ \t]*([A-Za-z_][-A-Za-z0-9_]*)[ \t]*:.

Abbreviation: I agree that the shortest unique match from the left should work. When you have this ok-file displayed by running ok:

1: echo "The first command is also anonymous"
2: echo "Second numbered command"
target: echo "First named command"
listing: ls -lahe@O
pick: printf "Type your pick: "; read MY_PICK
Pin: printf "Enter your nicest pin: "; read MY_PIN

One could run the target-line by ok target and also by ok t, because there is no other named line or internal command starting with a t. The shortest way to run the target listing would be to type ok listi because of the internal command list. To run pick, the minium one could type is ok pi, because ok p is a shortcut to the internal command list-prompt. The command ok P would run Pin, because of the case-sensitive matching.

I think the internal commands and the abbreviated shorthand for those should be excempt from the match algoritm. It would not make sense to type ok list-o for the list-once command or ok he for the help command. Also: the introduction of future internal commands might demote named lines to numbered ones. I guess that's a acceptable trade-off.

Errors: If a command is not recognized, or there are multiple lines found, ok should provide an error message. Ideally, it should work well with the utility thefuck. I guess that this mean if an error is encountered, ok should provide one ore more hints. However, thefuck accepts all kinds of hints, so we need to see what we like best.

Now, when typing ok lis the error message Unknown command/option 'lits' is produced. Ideally, it would say something like Did you mean: ok list. We should research what the best way is to determine these suggestions. When there are multiple alternatives, we could list these.

Formatting: ok-bash does do some formatting, like right-aligning the numbers, so the colons (currently dots) "sit" on top of each other. I think we just keep this behaviour, but not let the named lines participate in this rule. So only the colons of the numbers will be aligned. The coloring of numbered and named targets will help to recognize the names. And if one is so inclined, manually formatting can be applied by adding whitespace.

doekman commented 4 years ago

You can see progress in the branch named-lines.

secretGeek commented 4 years ago

You said:

I think targets only contain letters, digits, underscore and dash, with a length of at least one, always start with a letter or a underscore (starting with number of dash leads to command-line argument problems).

Here's how you described it:

^[ \t]*([A-Za-z_][-A-Za-z0-9_]*)[ \t]*:.

And here's how it looked for me in the powershell version:

[regex]$rx = "^[ `t]*(?<commandName>[A-Za-z_][A-Za-z0-9-_]*)[ `t]*\:(?<commandText>.*)$";

(Powershell uses backtick-t for tabs).

Here's my new idea.... I think that it would be good to allow dots, "." in the command name, (but not in the first character)

Dots serve a useful purpose when naming things (e.g. name-spacing), and since naming is hard, it might make things easier for people.

cheers lb

doekman commented 4 years ago

Hi Leon,

Dots in names would make sense.

And since names in makefiles (targets) can actually be file names seperated by spaces (https://www.gnu.org/software/make/manual/make.html#Rule-Syntax https://www.gnu.org/software/make/manual/make.html#Rule-Syntax) I think we are good here.

I will add it.

Greetings, Doeke

Op 10 mei 2020, om 13:23 heeft Leon Bambrick notifications@github.com het volgende geschreven:

You said:

I think targets only contain letters, digits, underscore and dash, with a length of at least one, always start with a letter or a underscore (starting with number of dash leads to command-line argument problems).

Here's how you described it:

^[ \t]([A-Za-z][-A-Za-z0-9])[ \t]*:. And here's how it looked for me in the powershell version:

[regex]$rx = "^[ t]*(?<commandName>[A-Za-z_][A-Za-z0-9-_]*)[t]\:(?.)$"; (Powershell uses backtick-t for tabs).

Here's my new idea.... I think that it would be good to allow dots, "." in the command name, (but not in the first character)

Dots serve a useful purpose when naming things (e.g. name-spacing), and since naming is hard, it might make things easier for people.

cheers lb

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/secretGeek/ok-bash/issues/24#issuecomment-626312659, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIJHNFZQQYKW2KD4FRNRBLRQ2FCXANCNFSM4MRQKNIQ.

doekman commented 4 years ago

I've just pushed two changes.

First: now named commands have a number too; only it's not displayed. So you can do ok show-env (within the repository) but ok 11 works too. It even uses less code than before!

Second: when you mis-spell a command, it now uses Levenshtein Distance over all commands to find suggestions. Check this:

$ ok colour.reset
ERROR: entered command 'colour.reset' could not be found in ok-file, suggested item:
    color.reset

The algorithm can also find multiple similar items:

$ ok color.tom
ERROR: entered command 'color.tom' could not be found in ok-file, suggested items:
    color.custom or color.text

I do a to-lower-case before calculating the Levenshtein distance, because I think this makes sense. It also works over internal commands (although I might change the error message):

$ ok lis
ERROR: entered command 'lis' could not be found in ok-file, suggested item:
    list

What do you think?

doekman commented 4 years ago

I pushed some minor bug fixes, and added a wiki page with all info/warning/error messages produced by ok-bash, so we can discuss them over there. Would that work?

secretGeek commented 4 years ago

Great idea. I want to join in on that discussion when I get a minute.

doekman commented 4 years ago

The internal commands have a one letter abbreviation (l, L, p and h):

Usage: ok [options] <named or numbered command> [script-arguments..]
       ok <internal command> [options]

command (use one):
  <number>            Run an unnamed command (the <number>th unnamed command) from the ok-file.
  <name>              Run an named command from the ok-file (starts with a letter or underscore, followed by same or dash or numbers)
  l, list             Show the list from the ok-file. Default command.
  L, list-once        Same as list, but only show when pwd is different from when the list was last shown.
  p, list-prompt      Show the list and wait for input at the ok-prompt (like --list and <number> in one command).
  h, help             Show this usage page.

I never use them, since I have a hard time remembering them, because I never use them.

It would be a breaking change, but I would like to drop the one character abbreviations. Any comments or suggestions?

secretGeek commented 4 years ago

sounds good to drop them if experience shows they're not used, as it also means they don't have to be reserved, and people can use them for their own user commands.

"h" for help is worth keeping though. Incidentally -- In ok-ps I will be supporting all of these for accessing help:

(of course backslash is never used for this kind of thing in linux and i don't expect ok-ps and ok-bash to be identical, just philosophically aligned)

I don't advertise all of those optional ways of accessing help. They're just for first time users to guide them toward a pit of success. (In powershell the convention of "help ok" will also work) I would need to warn the user if they name a command in a way that collides with those (but few such warnings are needed because most of them are not valid commands anyway due to not starting with a letter.)

doekman commented 4 years ago

Good input, I've removed the the abbreviations. To make it work nice, internal commands are added to the in-memory .ok file. The internal commands are only shown in verbose-mode (ok list --verbose or ok -v for short).

This way, internal commands are treated the same. So if you type ok list-pro the list-prompt command will be executed.

ok h will show help, but if there is a command hives it won't at the moment. I will look into this. Also, for first-time users it might be nice to add a man-page in the future...

Also: I now added "exact match", so if you type "ok args" you won't get an ambiguity error between "args" and "args-all".

There still are some minor things to work on though...