Macro
Examples of using macros in TheIDE
Macro.cpp
#include <Core/Core.h>
using namespace Upp;
CONSOLE_APP_MAIN
{
Cout() <<
"This application does nothing. It's only purpose is to demonstrate\n"
"the capabilities of the macro language embeded in TheIDE.\n"
"Try pressing Ctrl+Alt+S in TheIDE...\n";
}
Func.usc
// One of the functions used in the "Using functions" macro.
// As you can see, it can be defined in completely separate file.
fn FuncB(arg) {
return arg + "B";
}
Macro.usc
/* Welcome to the macro examples file! */
// The first function only serves as an introduction.
// It is bound to a keyboard shortcut, to make it easier,
// the rest of the macros can be invoked via Macro item in the menu.
macro "Start here" Ctrl+Alt+S {
// Open this file
EditFile("Macro", "Macro.usc");
// Set cursor to the start
SetCursor(0);
// Now you can continue reading and exploring the rest of the examples...
}
// Macros can call functions defined via "fn" keyword anywhere (even other files, see Func.usc).
// This is usefull e.g. when you want to share some funcionality between several macros.
macro "Using functions" {
// This function opens the example file, moves cursor at the end and appends some strings
// generated by functions.
EditFile("Macro","example.txt");
MoveTextEnd();
Insert("\n " + FuncA("C") + FuncB("D") + " \n");
}
fn FuncA(arg) {
return FuncB(arg + "A");
}
/* Chapter 1: Methods controlling the editor */
macro "1 Editor":"1.1 File name" {
ClearConsole();
Echo("Currently edited file is '" + FileName() + "'");
}
macro "1 Editor":"1.2 Opening file" {
// EditFile can be used with package and file names, as seen here, or it can ba called
// with single parameter containing full path to a file.
EditFile("Macro","example.txt");
}
macro "1 Editor":"1.3 Closing file" {
// Save the file first, to be sure
SaveCurrentFile();
// Now we can close it
CloseFile();
}
/* Chapter 2: Methods for automatic text editing */
macro "2 Editing":"2.1 Select all" {
// Again, make sure we use the testing file
EditFile("Macro","example.txt");
// This moves the cursor at the begining of file (the same can be achieved with SetCursor(0);)
MoveTextBegin();
// Now we move the cursor at the end of file. The parameter says that we want to select all
// the text in between the previous and new position.
MoveTextEnd(1);
}
macro "2 Editing":"2.2 Cursor position" {
EditFile("Macro","example.txt");
// We can get curent cursor position (in characters from start)...
pos = GetCursor();
// ... which can be used to calculate line number ...
line = GetLine(pos);
// ... and also position within the line
col = GetColumn(pos);
// Now we move at the end of file and insert a string summarizing what we found out
MoveTextEnd();
Insert("Line:"+to_string(line)+", Col:"+to_string(col)+", Pos"+to_string(pos)+"\n");
// And finally, we put the cursor back where it originally was, just for users convenience
SetCursor(pos);
}
macro "2 Editing":"2.3 File info" {
EditFile("Macro","example.txt");
pos = GetCursor();
// Another set of informations we can get from the editor methods is how many text is there
length = GetLength();
// And also how many lines
lines = GetLineCount();
// Again, we append the info at the end and return to original position
MoveTextEnd();
Insert("Length:"+to_string(length)+", Lines:"+to_string(lines)+"\n");
SetCursor(pos);
}
macro "2 Editing":"2.4 Complex example" {
/* This function analyzes a document (example.txt) and prints a histogram of character
* usage at the bottom. It could probably be implemented better, faster or both,
* but it is intentionaly left as is, to demonstrate that even simple macro language
* can be used to achieve quite complex tasks.
*/
// how many lines should we use to print the histogram
height = 20;
// set active file to the example text
EditFile("Macro", "example.txt");
// remember cursor position, so we can return it at the end
pos = GetCursor();
// this is a little trick to make sure Esc knows that hist is a map, not an array
hist[""] = 0;
// iterate over entire document and count letters
length = GetLength();
for(i=0; i<length; i++){
x = ToLower(Get(i));
// change the key for non-printable
if(x[0]<=32)
x="";
// initialize if it is first encounter, otherwise just increse value
if(is_void(hist[x]))
hist[x] = 1;
else
hist[x]++;
}
// delete non-printable
hist[""] = void;
// make a line of '=' with same length as we have columns
sep = "+" + len(hist) * "-" + "+";
// insert top line
MoveTextEnd();
Insert("\n"+sep+"\n");
MoveTextEnd();
// compute maximum for scaling
max = height;
for(i in hist)
if(hist[i]>max)
max = hist[i];
// get sort order
k = sort(keys(hist));
// plot the histogram, left to right, top to bottom
for(i=height; i>0; --i){
Insert("|");
MoveRight();
for(j in k){
if(hist[k[j]]/max*height >= i)
Insert("#");
else
Insert(" ");
MoveRight();
}
// print y-axis legend
Insert("|"+to_string(int(i*max/height))+"\n");
MoveTextEnd();
}
//insert bottom line
Insert(sep+"\n");
MoveTextEnd();
// print x-axis legend
Insert(" ");
MoveRight();
for(j in k) {
Insert(k[j]);
MoveRight();
}
Insert("\n");
// return cursor to original position
SetCursor(pos);
}
macro "3 User interaction":"3.1 Using console" {
// It is a good idea to clean the console before printing something in it, because text
// left from previous actions might confuse the user
ClearConsole();
// You already seen Echo being used to inform user in some of the examples above...
// Important point is, that the console will be shown if it is hidden as soon
// as you Echo() something.
Echo("Hello wolrd!", "This is just a test...");
}
macro "3 User interaction":"3.2 Input" {
ClearConsole();
// The Input() function can be called to get some values from user. It returns array
// of strings containing the values entered into the dialog.
a = Input("Some number","Some string");
// If you want to use it to get some number, you need to convert it from string and check
// that it was really a number
n = to_number(a[0]);
if (is_void(n)){
Echo("ERROR: '" + a[0] + "' is not a number.");
return;
}
// Now you can safely use the obtained data
Echo("The entered number was "+to_string(n),
"The string was '" + a[1] + "'");
}
/* Chapter 4: Methods that give you informations about the development environment */
macro "4 Informative":"4.1 Package info" {
ClearConsole();
// There are 4 functions that can be used to find out what packages and files current
// project consists of.
Echo("ActivePackage()=\"" + ActivePackage() + "\"",
"MainPackage()=\"" + MainPackage() + "\"",
"PackageDir()=\"" + PackageDir() + "\"",
"PackageDir(\"plugin/z\")=\"" + PackageDir("plugin/z") + "\"",
"PackageFiles()=" + to_string(PackageFiles()),
"PackageFiles(\"plugin/z\")=" + to_string(PackageFiles("plugin/z")));
// Additionaly, the two of them which accept package name as a parameter can be also used
// to query packages not used in current project
Echo("PackageDir(\"plugin/gif\")=\"" + PackageDir("plugin/gif") + "\"",
"PackageFiles(\"plugin/gif\")=" + to_string(PackageFiles("plugin/gif")));
}
macro "4 Informative":"4.2 Build config info" {
ClearConsole();
// Another four methods inform about the build environment settings
Echo("Assembly()=\"" + Assembly() + "\"",
"Flags()=" + to_string(Flags()),
"BuildMethod()=\"" + BuildMethod() + "\"",
"BuildMode()=\"" + to_string(BuildMode()) + "\"");
// You might have noticed that BuildMode() returns number, but it can be easily converted:
modes = [ "Debug", "Optional", "Speed", "Size" ];
Echo("Build mode is set to '" + modes[BuildMode()] + "'.");
}
macro "5 Executing/Building":"5.1 Execute" {
ClearConsole();
// An external command can be executed with Execute, the output will be printed in console
Execute("echo Hello world");
}
macro "5 Executing/Building":"5.2 Launch" {
// this should work on Win and do nothing on Linux
Launch("cmd.exe");
// this should do nothing on Win and work on Linux
Launch("/usr/bin/xterm");
}
macro "5 Executing/Building":"5.3 Build" {
ClearConsole();
// Build can be used to automatically build current project.
Build();
}
macro "5 Executing/Building":"5.4 BuildProject" {
ClearConsole();
// Get .upp file location for another package
upp = PackageDir("umk") + "/umk.upp";
// Build that package with SSE2 build flag
BuildProject(upp, "SSE2");
}
|