Managing your files and applications
Adding files and directories
You can add files to the RefactorErl database by calling the add function with either a filename as a string or a module name as an atom. Note that in the latter case, "ri" defaults to the current working directory (which you may work around by including a path in your singe-quoted atom). If you specify a directory instead of a regular filename, then it will be recursively traversed. You may just as well give a list of atoms or strings to add more files at once. All of the following example commands would add the same file:
cd(dir), ri:add(modname). ri:add('dir/modname'). ri:add(['dir/modname']). ri:add("dir/modname.erl"). ri:add("/current/dir/modname.erl"). ri:add("path_to_dir/dir").
Usually, Erlang source files (having the extension .erl) are loaded into RefactorErl. In addition, RefactorErl is also capable of loading compiled .beam files.
ri:add("compiled.beam").
Note that this feature is applicable only to those .beam files that were compiled with the debug_info option. Also note that the resulting file will be pretty printed by RefactorErl.
Dropping files and directories
The module displays the progression of loading. Removing files from the database is similarly easy and also recursive. The following will equally work:
ri:drop(modname). ri:drop([modname]). ri:drop("dir/modname.erl"). ri:drop("/current/dir/modname.erl"). ri:drop("path_to_dir/dir").
Adding applications
Modules can be loaded as applications, but some configurations has to be made before. The configurations can be done manually by setting the enviromental nodes, or can be done automatically by using the Emakefile handling functions (beta version) of the tool.
Adding applications by manual configuration
The manually configuration can be done by using the ri or the ris module.
Modules can be loaded as applications, but the base of your library has to be set before:
ri:addenv(appbase, "path/to/my/applib").
If the application has additional include directories, then these directories has to be also set in advance:
ri:addenv(include, "path/to/my/incldir").
If the application build process contains compile-time macros, then these macros also can be set:
%if it is only used in ifdef forms. ri:addenv(def, my_macro). ri:addenv(def, {my_macro, my_macro_value}).
If the include forms of the application contain OS based enviromental nodes, then these nodes can be set:
ri:addenv(env_var, {os_env_name, "os_env_path"}).
Let's see an example:
The Emakefile has the following contents:
{"/home/user/dev/lib/app1/src/*", [{i,"/home/user/dev/lib/"}, {d,"MY_MACRO", "ITS_VALUE"}, {outdir,"/home/user/dev/lib/app1/ebin"}]}. {"/home/user/dev/lib/app2/src/*", [{i,"/home/user/dev/lib/"}, {d,"MY_MACRO", "ITS_VALUE"}, {outdir,"/home/user/dev/lib/app2/ebin"}]}. {"/home/user/dev/lib/app3/src/*", [{i,"/home/user/dev/lib/share/include/"}, {i,"/home/user/dev/lib/"}, {outdir,"/home/user/dev/lib/app3/ebin"}]}.
To add app1, app2, app3 to RefactorErl you should do the followings:
% add app1, app2 with the same configuration ri:addenv(appbase, "/home/user/dev/lib/"), ri:addenv(def, {'MY_MACRO', "ITS_VALUE"}), Apps = [app1, app2], [ri:add(home, App) || App <- Apps]. % add app3 after the configuration has been modified ri:delenv(def), ri:addenv(include, "/home/user/dev/lib/share/include/"), ri:add(home, app3).
You can check the already given application base directories by listing all of the enviromental nodes:
ri:envs().
It is possible to delete the defined environment variables:
ri:delenv(include).
Or you can set an environmental variable to another value:
ri:setenv(env_name, "path/to/new_value").
The following enviromental nodes can be set via the ri module:
output: Where does RefactorErl write changes in?
appbase: The list of the used application based directories.
include: The list of the used include directories.
def: The list of the compile-time macros.
env_var: The list of the OS based enviromental nodes.
Adding applications using the Emakefile handling functions
Applications with their proper configurations (such as include paths, macros), or only the configurations, which are defined in an Emakefile, can be added by executing only one command. The given Emakefile is parsed then the configurations and the adding procedure are handled automatically by the tool. The functionality is available in the ri module and also available in the ris module.
By executing one of the following commands:
EmakeFilePath = "/absolute_path_to_the_emakefile", ri:add_by_emakefile(EmakefilePath). % whether a list of Emakefiles are present. EmakeFiles = ["/absolute_path_to_the_emakefile1", "/absolute_path_to_the_emakefile2"], ri:add_by_emakefile(EmakeFiles).
the applications which are defined in the given Emakefile(s) are loaded into the database. Please note, that
- the configurations, which are defined in the Emakefile, only stored temporary, while the adding procedure has not been finished;
- if the Emakefile contains relative path, then it will be converted absolute by using the path of the Emakefile as base.
If your apllications have been loaded by using ri:add_by_emakefile/1 and any of the applications uses irregular include path or compile-time macro,
then these applications should be updated by using ri:add_by_emakefile/1, or by loading the configuration ri:load_configuration/1 then by executing ri:database_synchronization/0.
If the loaded configuration is not needed further then it may be unloaded by executing ri:unload_configuration/1.
Applications can be dropped from the database in the same way as the normal files.
Refreshing your database
If your files has been changed in the disk, since the last load, then these files may be re-added to the database to gather fresh information about the files from the tool. This can be easily done, by executing one of the following commands:
ri:database_synchronization(). ris:database_synchronization().
Gathering information about your database
For convenience, both the filenames and the directory names can be given as atoms as well as strings. The list of loaded files can be obtained by calling
ri:ls().
This call also displays the status of the loaded files (error or no_error). If the module m is loaded,
ri:ls(m).
will give information about the functions, records and macros in the file. The contents of a file can be listed by
ri:cat(ModFile).
The content of a function can be listed by
ri:cat(ModFile, {FunName,Arity}).