I have a personal productivity problem as I have a bunch of programs all over the place on my Desktop or in my Program Files Menu. I tried many launchers freewares but none really satisfied me so I finally decided to use Rebol Shell as my launcher. It’s also a great example of a context when you need to use the Bind function in Rebol.
So let’s say I have a list of programs I want to launch by just typing a keyword in Rebol Shell. For example, Notepad would launch my favorite notepad2 program in c:\program files\notepad2\notepad2.exe. So I created a file list shell.list.txt to store them as a sample:
"notepad" "c:\program files\notepad2\notepad2.exe" "calc" "c:\windows\system32\calc.exe" "WebDevExpress" "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\VWDExpress.exe"
If this file is located in data sub-directory within the current directory (generally the directory of the current script that is executing), it will be loaded into a Rebol block with this instruction:
shell.list: load %data/shell.list.txt
Then the run function will refer to it to get the real path with the Rebol Select function:
Run: func[exe-path][
if/else not none? it: select shell.list exe-path [
call quote it
][
;in case keyword cannot be found, one supposes it's the full path
call quote exe-path
]
]
Copy and paste it into Rebol Console along with this mock data:
shell.list: ["notepad" "c:\program files\notepad2\notepad2.exe"
"calc" "c:\windows\system32\calc.exe"
"WebDevExpress" "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\VWDExpress.exe"]
So that you can test it by typing
run "c:\windows\system32\calc.exe"
or just the keyword
calc
This latter won’t work. Why? Because calc has not yet been defined as a command in Rebol. To do so, you would create a calc function like this:
calc: func[][
run "c:\windows\system32\calc.exe"
]
Copy and paste the code above and test calc again, this time it should work.
Now, it would be tedious to define each keyword by creating a new function by hand whereas the procedure is rather generic. So naturally you’d like to use a dynamic generator function to do this for you something like this:
foreach [name path] shell.list [
func-body: to-block rejoin ['run " " {"} name {"}]
set (to-word name) make function! [] func-body
]
If you execute the code above, you could see that it created notepad and calc functions by using the rebol source command:
>> source notepad
notepad: func [][run "notepad"]
>> source calc
calc: func [][run "calc"]
>>
Now if you want to test the calc keyword again, you would get this bad “surprise”:
>> calc
** Script Error: run word has no context
** Where: calc
** Near: run "calc"
because run is an unknown word within the context of func-body you created at runtime within the foreach loop. So you have to bind run to the func-body context by using the bind function like this:
set (to-word name) make function! [] bind func-body 'run
so that you can copy and paste the foreach loop once again:
foreach [name path] shell.list [
func-body: to-block rejoin ['run " " {"} name {"}]
set (to-word name) make function! [] bind func-body 'run
]
Finally typing the calc keyword in Rebol Console should launch the calculator !
To have all this automatically at Rebol launch, put these functions in User.r.


















No comments yet.