2019-12-15

32: Use Any Text Editor Instead of the LibreOffice Basic IDE

<The previous article in this series | The table of contents of this series | The next article in this series>

It is not just imagination that the LibreOffice or Apache OpenOffice Basic IDE is not-so-un-clumsy. You do not have to use it.

Topics


About: UNO (Universal Network Objects)
About: LibreOffice
About: Apache OpenOffice
About: LibreOffice Basic
About: Apache OpenOffice Basic

The table of contents of this article

Notation

  • 'Office' means LibreOffice or Apache OpenOffice.

Starting Context



Target Context


  • The reader will know how to use a text editor instead of the Office Basic IDE.
Stage Direction
Here are Hypothesizer 7, Objector 32A, and Objector 32B in front of a computer.


Orientation


Hypothesizer 7
In this article, we will know how to use a text editor instead of the not-so-un-clumsy LibreOffice or Apache OpenOffice Basic IDE.

Objector 32A
"not-so-un-clumsy"? Why do you speak in such a roundabout way? Say it straight!

Hypothesizer 7
Say what, sir?

Objector 32A
Say that it's clumsy.

Hypothesizer 7
Well, I wonder whether that is an appropriate expression . . .

Objector 32A
Or say that it's irritating!

Hypothesizer 7
Well, . . .

Objector 32A
Or is 'sucky' the appropriate expression?

Hypothesizer 7
. . . There are individual differences in the impressions.

Objector 32A
What is the suckiest about the IDE for you?

Hypothesizer 7
. . . What is the most not-so-un-clumsy thing about the IDE for me is that the source code area does not wrap long lines.

Objector 32A
Year, that sucks. I can't see the whole line at once. You know, programming is not 'writing characters sequentially once from beginning to end'; I go to and fro, and frequently, I ponder on a line or block in order to figure out what's wrong with it. Not being able to see the whole line or block is fatal.

Hypothesizer 7
. . . Another not-so-un-clumsy thing about the IDE for me is that a double click selects the '_' separated part of the word, which is really . . .

Objector 32A
irritating, isn't it?

Hypothesizer 7
. . . inconvenient, I mean. While I use '_' in all the variable names in principle, I cannot select variable names easily.

Objector 32A
That sucks, huh?

Hypothesizer 7
. . . As another, the IDE does not allow me to view multiple modules at once, which is very unhandy.

Objector 32A
Ah, you said that. Editing a source file with referring to another source file is a usual practice, which is not supported! The IDE has not reached the minimum requisite level as a programming editor!

Hypothesizer 7
. . . As another, the left-side tree view of libraries-modules is . . .

Objector 32A
sucky.

Hypothesizer 7
. . . unhelpful, I mean. Usually, such a tree view would let me create libraries and modules, rename libraries and modules, and delete libraries and modules, but that tree view does not let me do anything of them . . .

Objector 32A
You begin to be filled with anger, huh?

Hypothesizer 7
. . . I have my emotions under control, sir.

Anyway, in short, the IDE is . . .

Objector 32A
sucky.

Hypothesizer 7
. . . not so un-clumsy. So, I will dismiss the IDE and use my favorite text editor instead, which is the theme of this article,

Objector 32B
I agree that the IDE sucks, or is not so un-clumsy, but I can't help but use the IDE when I debug a macro, can I?

Hypothesizer 7
Madam, actually, that is an important issue, which we will discuss in a later section.


Main Body


1: Identifying the Base Directory of Basic Source Files


Hypothesizer 7
First, let us identify the base directory of Basic source files.

It depends on the environment, of course, but for LibreOffice 6.0.7 in my Linux, it is '~/.config/libreoffice/4/user/basic'; for LibreOffice 6.3.3 in my Windows, it is 'C:\Users\%the user name%\AppData\Roaming\LibreOffice\4\user\basic'. . . . You will be able to guess it for your environment.

Objector 32B
You are talking about only libraries contained in the application, not about any library contained in a document, aren't you?

Hypothesizer 7
Ah, you are right. As I do not have any habit of putting any Basic code into any document, I did not think about it at all . . .

Well, if a Basic library has to be put into a document, I would develop it as a contained-in-the-application library first, and then, put it into the document (export and import the library). I do not guess that we can directly develop a contained-in-a-document library with an external text editor.


2: Creating any Library


Hypothesizer 7
As a preparation, if an Office instance is already up, we shut it down.

Objector 32B
Do I have to do that?

Hypothesizer 7
Not in all the cases, but it is safe to do so.

Objector 32B
How dangerous is it if I do not do so? An explosion?

Hypothesizer 7
Not so dangerous, but the Office instance may not recognize the new libraries until it is restarted, and may erase our configurations, probably, when it shuts down.

Objector 32B
Ah.

Hypothesizer 7
In order to create any library, we create the directory of the library name in the Basic base directory and edit the 'script.xlc' file in the Basic base directory to add a 'library:library' element in the 'library:libraries' element, like this.

@XML Source Code
 <library:library library:name="theBiasPlanet_coreUtilities" xlink:href="$(USER)/basic/theBiasPlanet_coreUtilities/script.xlb/" xlink:type="simple" library:link="false"/>

Objector 32B
Um? Hmm, 'theBiasPlanet_coreUtilities' is the library name, huh?

Hypothesizer 7
Yes. Then, in the library directory, we create the 'script.xlb' file, with these contents.

@XML Source Code
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE library:library PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "library.dtd">
<library:library xmlns:library="http://openoffice.org/2000/library" library:name="theBiasPlanet_coreUtilities" library:readonly="false" library:passwordprotected="false">
</library:library>

Objector 32B
Hmm, I should change the single library name, right?

Hypothesizer 7
Yes.


3: Creating any Module


Hypothesizer 7
As is the same with creating any library, as a preparation, if an Office instance is already up, we shut it down.

In order to create any module, we create the file of the module name + '.xba' in the library directory and registers the module in the 'script.xlb' file, as a 'library:element' element in the 'library:library' element, like this.

@XML Source Code
 <library:element library:name="collectionsHandling"/>

Objector 32B
'collectionsHandling' is the module name, huh?

Hypothesizer 7
Yes. In the module file, we write only this, for the present.

@XML Source Code
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
<script:module xmlns:script="http://openoffice.org/2000/script" script:name="collectionsHandling" script:language="StarBasic" script:moduleType="normal">Option Explicit

</script:module>

Objector 32B
I should change the single module name. . . . Well, I wonder whether this is really less bothersome than using the IDE . . .

Hypothesizer 7
Well, you can do those creating libraries and modules parts using the IDE and then, switch to using a text editor, but after you are accustomed to doing things without the IDE, you may become preferring the above ways. In fact, they are not bothersome as they might seem right now, because you will just copy things and modify only a few parts.

Objector 32B
I may.


4: Coding the Module


Hypothesizer 7
Note that unless we add, remove, or rename any library or module, we do not need to shut the Office instance (if there is) down.

Objector 32B
That's good.

Hypothesizer 7
Now, we do the coding in the 'script:module' tag in the module file, to our hearts' content.

Objector 32B
With our favorite editors . . .

Hypothesizer 7
Yes. As I use 'vim' for any coding, it is much smoother and pleasanter than using the . . . IDE.

Objector 32A
You mean the sucky IDE.

Hypothesizer 7
. . . A note is that as the code is inside the XML tag, we have to escape the characters, '<', '>', and '&', as '&lt;', '&gt;', and '&amp;', respectively.

Objector 32A
Ah, that's better than using the IDE that doesn't wrap lines and doesn't show multiple source files at once.

Hypothesizer 7
Although the IDE escapes also ''' and '"' as '&apos' and '&quot;', respectively, that is not necessary, as they are allowed in any XML tag text.


5: Debugging the Code


Hypothesizer 7
Before we invoke any subroutine, probably, we will want to compile the modules.

Objector 32A
Will I? I can invoke the subroutine without the bother of compiling, can't I?

Hypothesizer 7
You can, but Basic will tend to show enigmatic errors if any syntax error hides somewhere in the whole code.

Objector 32A
It tends to show enigmatic errors in whatever condition, in my experiences . . .

Hypothesizer 7
The errors will tend to be much more enigmatic.

Objector 32A
How much more?

Hypothesizer 7
For example, although an error happens at a line, the line is not responsible at all, but a syntax error in another module is.

Objector 32A
That is too enigmatic . . .

Hypothesizer 7
So, probably, you will want to be sure that all the modules will compile fine.

Objector 32A
How can I compile a module without using the sucky IDE?

Hypothesizer 7
As far as I know, we have to compile any Basic module using the IDE.

Objector 32A
Huh? Is that the end? Do I have to touch the sucky IDE, after all?

Hypothesizer 7
As avoiding touching the suc- . . . not-so-un-clumsy IDE is our primal objective here, I have created an external program that automates compiling. So, we use the IDE, but not touch it, or at least, touch it as little as possible.

Objector 32A
"automates"?

Hypothesizer 7
When we execute the compiling program, the IDE automatically starts up and automatically compiles the specified module, the specified library, or all the libraries.

Objector 32A
. . . What if the IDE reports a compile error?

Hypothesizer 7
It will report the error in a message box as usual. So, you will have to touch the message box to close it, if you do not mind.

Objector 32A
I don't say to mind touching even such a message box. . . . I certainly didn't say that the IDE was a pathogen.

Hypothesizer 7
In fact, I have created a Java version and a Python version.

Objector 32A
Why didn't you create it in Basic?

Hypothesizer 7
Because Basic can do compiling a module or do running a program, but not both, at the same time: any Basic program cannot invoke any compiling because it is running.

Objector 32A
Ah . . ., so, where are the programs?

Hypothesizer 7
They are included in this ZIP file, and how to build them is explained here.

Objector 32A
. . . Do I have to build a development environment and build them from the source files?

Hypothesizer 7
The Python version does not necessarily have to be built, but it assumes a Python of 3.6 or newer and pyperclip.

Objector 32A
I can just install a newer Python, right?

Hypothesizer 7
Not so right, actually. It is a UNO program, and your Office product dictates the Python version (an explanation for Linux or for Windows).

Objector 32A
Oh. . . . So, if my Office product dictates an older version, I will have to use the Java version . . .

Hypothesizer 7
That is the reason why I am introducing also the Java version. . . . Or you can modify the Python version to adjust to your older Python.

Objector 32A
How?

Hypothesizer 7
In fact, the Python program is for 3.6 or newer Pythons only because it uses the variable type annotations feature; with the variable type annotations removed, it would work fine for Python 3.5.

Objector 32A
Why don't you remove them yourself?

Hypothesizer 7
Because I am not any fan of so-called "duck typing" and I never intend to write any Python code without the variable type annotations.

Objector 32A
. . . You suck.

Hypothesizer 7
After the Office instance has been started up as a UNO server, the Java version can be executed like one of these (via Gradle or directly), in a terminal with the current directory at the project directory, where "${HOME}/myApplications/libraries/javaFx/lib", "/usr/lib/libreoffice", "${HOME}/.config/libreoffice/4/user/basic", "Standard", and "Module1" are the JavaFX path, the Office path, the Basic source base path, the library name, and the module name, respectively (please tweak the commands for Windows).

@bash Source Code
gradle i_executeJarTask -Pc_mainClassName="theBiasPlanet.basicCompiler.programs.BasicCompilerConsoleProgram" -Pc_commandLineArguments="socket,host=localhost,port=2002,tcpNoDelay=1;urp;StarOffice.ComponentContext ${HOME}/.config/libreoffice/4/user/basic Standard Module1"

@bash Source Code
bash -c "export URE_BOOTSTRAP=\"file:////usr/lib/libreoffice/program/fundamentalrc\"; java --module-path ${HOME}/myApplications/libraries/javaFx/lib --add-modules=javafx.controls,javafx.fxml -Dprism.order=sw -classpath target/theBiasPlanet.basicCompiler.jar:../unoUtilitiesToBeDisclosed/target/theBiasPlanet.unoUtilities.jar:../coreUtilitiesToBeDisclosed/target/theBiasPlanet.coreUtilities.jar:/usr/lib/libreoffice/program/classes/unoil.jar:/usr/lib/libreoffice/program/classes/jurt.jar:/usr/lib/libreoffice/program/classes/ridl.jar:/usr/lib/libreoffice/program/classes/juh.jar theBiasPlanet.basicCompiler.programs.BasicCompilerConsoleProgram \"socket,host=localhost,port=2002,tcpNoDelay=1;urp;StarOffice.ComponentContext\" \"${HOME}/.config/libreoffice/4/user/basic\" \"Standard\" \"Module1\""

The Python version can be executed like one of these (via Gradle or directly), in a terminal with the current directory at the project directory, where "/usr/lib/libreoffice", "${HOME}/.config/libreoffice/4/user/basic", "Standard", and "Module1" are the Office path, the Basic source base path, the library name, and the module name, respectively (please tweak the commands for Windows).

@bash Source Code
gradle i_executePythonExecutableFileTask -Pc_mainModuleName="theBiasPlanet.basicCompiler.programs.BasicCompilerConsoleProgram" -Pc_commandLineArguments="socket,host=localhost,port=2002,tcpNoDelay=1;urp;StarOffice.ComponentContext ${HOME}/.config/libreoffice/4/user/basic Standard Module1"

@bash Source Code
bash -c "export PYTHONPATH=\"${PYTHONPATH}:source/python:/usr/lib/libreoffice/program:../unoUtilitiesToBeDisclosed/source/python:../coreUtilitiesToBeDisclosed/source/python\"; export URE_BOOTSTRAP=\"vnd.sun.star.pathname:/usr/lib/libreoffice/program/fundamentalrc\"; python3 -m theBiasPlanet.basicCompiler.programs.BasicCompilerConsoleProgram \"socket,host=localhost,port=2002,tcpNoDelay=1;urp;StarOffice.ComponentContext\" \"${HOME}/.config/libreoffice/4/user/basic\" \"Standard\" \"Module1\""

If an error that pyperclip could not find a copy/paste mechanism for your system occurs, please consult this (I have installed 'xsel').

Objector 32A
I want to compile a whole library, actually.

Hypothesizer 7
Please omit the module name, and it will compile the whole library.

Objector 32A
Actually, sometimes, I want to compile all the libraries.

Hypothesizer 7
Please omit also the library name, and it will compile all the libraries.

Objector 32A
Oh.

Hypothesizer 7
Please note that the clipboard datum before the program execution may be lost.

Objector 32A
"may"?

Hypothesizer 7
The Python version should restore the clipboard datum only if it is a text datum, because pyperclip can copy and paste only text data; the Java version tries to restore the clipboard datum, but without any success in my Linux environment: any clipboard datum set by the Java program is cleared after the program termination, I do not know why.

Objector 32A
Why are your programs meddling with the clipboard, in the first place?

Hypothesizer 7
That is because the IDE will not reload any modified source file; so the programs have to copy and paste the modified contents onto the IDE.

Objector 32A
. . . They do some tricky things, huh?

Hypothesizer 7
Actually, yes. So, as the IDE flickers while the programs manipulate it, please leave it alone unless a message box demands your action.

Objector 32A
I see.

Hypothesizer 7
In order to invoke any subroutine, we do not need the IDE.

For example, we can invoke the subroutine with an operating system command, like this, where "Standard", "Module1", and "Main" are the library name, the module name, and the subroutine name, respectively.

@bash or cmd Source Code
soffice "vnd.sun.star.script:Standard.Module1.Main?language=Basic&location=application"

Objector 32A
Hmm.

Hypothesizer 7
If a runtime error occurs and is not so-called catched, the IDE will automatically start up and show the error.


6: How to Prevent the Office Instance from Overwriting Some Source Files


Hypothesizer 7
Actually, the Office instance gratuitously tries to overwrite some source files, even if we do not ask it to save the files at all.

Objector 32A
Ah. I have forgotten to mention that another reason why Basic IDE is sucky.

Hypothesizer 7
. . . Well, that is not any critical problem, but an annoyance is that the Basic IDE needlessly escapes ''' and '"', which I am not happy about.

Objector 32A
It is insane that an IDE forcefully saves files unrequestedly . . .

Hypothesizer 7
An end run I take in Linux is to change the owner of the source files to another user, revoke the writing permission from the Office instance user, and edit the source files as the another user.

Objector 32A
Ah, I have to do that . . .

Hypothesizer 7
That is not particularly difficult as we can just use 'chown', 'chmod', and 'su'.

When the Office instance shuts down, it complains some IO errors, but I just ignore them.

Objector 32B
How about Windows?

Hypothesizer 7
Honestly, I have not tried it yet; an issue will be how to execute the editor as the another user.


7: The Conclusion and Beyond


Hypothesizer 7
The Basic IDE is not so un-clumsy; it may be better to use our favorite text editors instead.

While we have to use the IDE in order to compile the modules, I have created some programs that automates compiling. The programs are also useful for reloading the modified modules.

Any subroutine can be easily invoked from outside the Office instance, but invocation of any function with the arguments will require some programming, which will be discussed in a future article.


References


<The previous article in this series | The table of contents of this series | The next article in this series>