$Id: monkeyfish.sgm 137 2006-03-06 03:14:56Z jimbag $
Copyright © 2006 J. Knight
$LastChangedDate: 2006-03-05 22:14:56 -0500 (Sun, 05 Mar 2006) $
Abstract
This document describes the MonkeyFish Editor version 0.1.
MonkeyFish is a text editor with features oriented toward programmers and programming.
Table of Contents
List of Figures
List of Tables
MonkeyFish is a text editor with features oriented toward programmers and programming. It aims to be as general as possible so as to be useful in as wide an array of tasks as possible.
MonkeyFish was born of the need to have an environment that was familiar and consistant and across platforms and programming language specificities. Moving back and forth between OS/X and Linux for programming tasks, it became tedious to deal with the peculiarities of the different environments for editing and project management tasks. Even moving between language environments on the same platform can become irksome if your hotkeys are different or syntax highlighting appears differently.
MonkeyFish does not attempt to push you into a language centric enviroment. Eclipse, for instance, is an excellent environment with which to develop java applications but leaves a lot to be desired when handling other languages. Xcode, while attempting to be a generic build tool, fails to meet the customization level needed to manage projects in anything but a C-style build cycle. Although it allows you to edit python, it is cumbersome as an environment for building python applications or even simple web sites. The fact that it is only available on the mac not withstanding.
MonkeyFish offers:
A cross-platform solution available for X11, OS/X, Windows. MonkeyFish is built with wxWidgets, a cross-platform native UI framework.
A familiar editing environment with multiple open files, cut, copy, paste, undo, redo, syntax highlighting, autocompletion and macros. MonkeyFish utilizes the Scintilla editor.
An enviroment in which to manage disk files, copy, delete, rename, etc.
An environment with which to manage projects of source material used to produce products such as web sites and programs.
A scripting framework with which to customize the behavior of the environment to suit the production task at hand. MonkeyFish embeds and enhances the Lua language for scripting.
MonkeyFish, by design, does not offer some things you may be expecting to find in an IDE. There is no class browser or wizards or boxes popping up in the middle of your typing. There is no paper clip helper or UML editor. In fact, you can think of MonkeyFish not as an IDE (Integrated Development Environment) but as a UIDE (Unintegrated Delevelopment Environment). There are tools available that do class browsing, SCM, debugging, etc that are all specific and far more featureful then any one IDE can offer. MonkeyFish just gives you a way to hook those tools into your production cycle without trying to replace them.
For example, MonkeyFish does not know how to build anything nor does it care how you build anything. If you are using Java, then use Ant or Maven for your builds. If you are building C++ then Autotools or SCons may suit you. If you are building a Ruby app then you don't need to compile anything, just run it. MonkeyFish aims to make these things convienent without getting in the way of them. Want to use plain "cvs diff", go ahead. If you'd rather use Meld to view your diffs, it's easy to add it to the tool chain!
Table of Contents
The MonkeyFish enviroment is simple and clean. It mainly consists of a tabbed editor window that allows you to read and write text files and manipulate the contents. There are three panes available. The editor generally takes up most of the screen area. There is a sidebar to the left that contains a project view and a view to the disk and an output window at the bottom that show you the output from any executed commands. Both the sidebar and the output window can be hidden to keep thing uncluttered.
The editor is an embedded Scintilla editor that you may have encountered by using tools such as KDevelop or Anjuta. It is a full featured editing environment with syntax highlighting for many programming languages.
The side bar contains a project window and a directory window. The directory window gives full access to the disk and allows you to edit, delete, rename, create new folders and execute files. The project window allows you to gather resources you need to construct programs in a convienient tree along with the tools you may need for construction.
Table of Contents
You start the editor by clicking on it's icon or typing monkeyfish at the prompt.
bash$
monkeyfish
To create a new file, choose Ctrl-N) The application will then display a new tab in the editor window.
-> (To open a file, choose Ctrl-O). The application will open a file selector to allow you to choose a file. The file will be opened on a new tab on the editor window. If the file is already open, the tab for that file will be selected.
-> (To save a file, choose Ctrl-S) . The application will open a file selector to allow you to choose a file.
-> (You can edit text in the following ways:
Type new text from the keyboard.
Copy selected text to the clipboard. Ctrl-C)
-> (Delete or Cut selected text to the clipboard. Ctrl-X)
-> (Paste from the clipboard. Ctrl-V)
-> (
You can undo your last edit with Ctrl-Z).
-> (You can redo your last undo with Ctrl-Shift-Z).
-> (MonkeyFish has some more advanced features that are oriented toward programming and manipulating program code.
Set the syntax highlighting mode by choosing
-> and then selecting the language style you want to use.Syntax highlighting is confgured via scripts. Open the MonkeyFish launches.
-> menu and navigate to the syntax subdirectory and look at one of the sytax files therein for an example. You can add new languages there and they will be picked up the next timeCurrently there is no UI element to use to associate scripts with file extentions. If you want to add new associations you need to edit the config script by hand or the registry in windows (see below). Open the file "$HOME/.MonkeyFish" in GTK or "$HOME/Library/Preferences/MonkeyFish Preferences" in os/x
[files] [files/exts]
If those sections are not there you can add them. Underneath [files/exts] you can make your association to scripts by adding the file extention and the script name without the path like so...
[files] [files/exts] java=Java.mf xml=xml.mf html=xml.mf cpp=CPP.mf mf=Lua.mf
True to windows, MonkeyFish stores its settings in the registry rather then a text file. To edit these settings you need to go into the registry editor (regedit) and edit the tree beneath [HKEY_CURRENT_USER->Software->MonkeyFish]. You should be able to figure out the translation between the file based tree and the registry tree given the example above. In the future you will be able to edit these from the preferences dialog.
You can indent and unindent the current selection with Ctrl-]) and -> (Ctrl-[) respectively.
-> (You can select a block of text between braces by putting the caret before the brace in question and choosing
-> .There is a macro facility available via the Ctrl-1 to Ctrl-9 keys. Macros are MonkeyFish scripts that are accessable instantly with the above mentioned keys. Macros are hooked to scripts in your $SCRIPTDIR called "macro1.mf" up to "macro9.mf". They can perform any operation available to scripts.
For example, lets create a macro to insert a C-style comment. Open "Tools->Scripts" and edit the file "macro1.mf". Add the following text to it and save it...
comment = [[ /** * */ ]] assert( mf, "MonkeyFish not available") e = assert(mf.selected(), "No editor selected") e:insert( comment, e:go("bol") )
Now place the caret at the first line of a function or method definition in some code and press Ctrl-1.
Table 2.1. Editor Key Bindings
Key Binding | Description | |
---|---|---|
Down Arrow | Move caret down one line. | |
Shift Down Arrow | Move caret down one line extending the selection. | |
Ctrl Down Arrow | Scroll document down keeping the caret visible. | |
Up Arrow | Move caret up one line. | |
Shift Up Arrow | Move caret up one line extending the selection. | |
Ctrl Up Arrow | Scroll document up keeping the caret visible. | |
Left Arrow | Move caret left one character. | |
Shift Left Arrow | Move caret left one character extending selection. | |
Ctrl Left Arrow | Move caret left one word | |
Ctrl Shift Left Arrow | Move caret left one word extending selection. | |
Right Arrow | Move caret right one character. | |
Shift Right Arrow | Move caret right one character extending selection. | |
Ctrl Right Arrow | Move caret right one word | |
Ctrl Shift Right Arrow | Move caret right one word extending selection. | |
Home | Move caret to before first visible character on line. If it is already there move to the first character on line. | |
Shift Home | Like Home but extending the selection. | |
Ctrl Home | Move caret to the first position in the buffer. | |
Shift Ctrl Home | Move caret to the first position in the buffer, extending the selection. | |
End | Move caret to the last position on line. | |
Shift End | Move caret to the last position on line, extending the selection. | |
Ctrl End | Move caret to the last position in the document. | |
Shift Ctrl End | Move caret to the last position in the document, extending the selection. | |
Page Up | Move caret one page up | |
Shift Page Up | Move caret one page up, extending the selection. | |
Page Down | Move caret one page down | |
Shift Page Down | Move caret one page down, extending the selection. | |
Delete | Delete character to the right of the caret. | |
Shift Delete | Cut selection to the clipboard | |
Ctrl Delete | Delete the word to the right of the caret. | |
Shift Ctrl Delete | Delete from caret to the end of the line. | |
Insert | Toggle overtype mode. | |
Shift Insert | Paste | |
Ctrl Insert | Copy seleciton to the clipboard. | |
Backspace | Delete the selection, if no selection, delete character to left of caret. | |
Shift Backspace | Same as backspace | |
Ctrl Backspace | Delete word to the left of the caret. | |
Shift Ctrl Backspace | Delete from caret tot he start of the line. | |
Ctrl Z | Undo action | |
Shift Ctrl Z | Redo action | |
Ctrl X | Cut selection | |
Ctrl C | Copy selection | |
Ctrl V | Paste | |
Ctrl A | Select All | |
Tab | If selection is empty or all on one line, replace the selection with TAB character. If more then one line selected, indent the lines. | |
Shift Tab | Dedent the selected lines | |
Ctrl L | Cut line | |
Shift Ctrl L | Delete line | |
Ctrl T | Switch current line with previous line | |
Ctrl U | Transform selection to lowercase | |
Shift Ctrl U | Transform selection to uppercase | |
There is an emacs key compatibility mode because, lets face it, you can't really be productive as a programmer without emacs bindings. Of course it's not a fully compatible mode since MonkeyFish is not emacs, but there is enough to hopefully keep you comfortable and productive.
Table 2.2. Emacs Key Bindings
Key Binding | Description | |
---|---|---|
Ctrl-X Ctrl-F | Open a file | |
Ctrl-X Ctrl-S | Save file | |
Ctrl-X Ctrl-W | Save file as | |
Ctrl-X 0 | Close file | |
Ctrl-F | Forward character | |
Ctrl-B | Backward character | |
Ctrl-P | Previous line | |
Ctrl-N | Next line | |
Esc F | Forward word | |
Esc B | Backward word | |
Ctrl-A | Beginning of line | |
Ctrl-E | End of line | |
Esc > | End of document | |
Esc < | Beginning of document | |
Ctrl-W | Kill selection | |
Ctrl-K | Kill line | |
Ctrl-Y | Paste selection | |
Ctrl-_ | Undo edit | |
Ctrl-X Ctrl-R | Redo edit |
Table of Contents
Type stuff
Compile it
Run it
Fix it
Goto 1
The toolbar in the project window offers easy access to some common functions. You can open and save projects with the first two buttons.
The next three buttons are hooked into the "Tools" branch of the project tree. If you click on the "Build" button it looks for an entry called "Build" under the "Tools" branch and excutes that. It can either be a Shell tool or a Script tool. "Execute" and "Debug" work them same way. The tool itself can do anything you need so "Build" may run make or it may be hooked into a script that writes a letter to congress.
The popup menu in the project window offers access to various functions depending on the context.
Right-click on the project root:
Properties - allows you to manage project properties.
New Project - creates a new blank project.
New from template... - opens a new project and unzips it into the selected directory. Project templates are simply zip files with the project structure therein. As the files are written a simple substitution can can take place where any file that contains the text "$MF_PROJECT_NAME$" is substituted with the actual project name.
Open Project - opens a project.
Save Project - saves the current project.
Save Project As... - saves the current project under a new name.
Right-click on a file or directory:
Properties - allows you to view some file properties.
Edit - opens the file in the editor.
Rename - renames the file on disk.
Delete - deletes the file from the disk.
SVN or CVS submenu. - if you have SVN or CVS in the folder this file is in, the appropriate menu is displayed.
This branch allow you to organize your source material by grouping files and directories into sensible branches without the clutter of looking at the full file system.
Tools can either be shell commands or MonkeyFish scripts. You can add a new tool by right-clicking on the Tools item in the project tree and selecting either . A text input dialog will popup allowing you to enter the tool parameters. You can add separate commands, one per line or simply the path to a script if adding a script tool.
If you wanted to run "make" from a Build tool, you would name the tool "Build" and the command would be...
"make"
.
Multiple shell tool commands are entered one per line. For example to execute your wxpython program, add a tool called "Execute" and enter the following in the command window...
cd src python myWxPy.py
Some windows programs have no I/O streams so the default is to not try and collect output from shell tool commands. Running "make" will produce nothing in the output window. In order to see output from a command in the output window you should preface the command with a vertical bar '|' like: "cd src;|make". The bar is ignored on other platforms so you can leave it in your project if you are moving between platforms. If you try and collect output from a program that has no output streams, the program will not run. e.g. "|notepad" will not work but "notepad" works as expected.
Script tool commands are simply the path to the script itself. If you wanted to run a script called "debug.mf" you would simply add
"Debug#scripts/debug.mf"
. You can portably do pretty much anything you need to with a script command.
This tool is triggered, if present, from the toolbar Build button. If you wanted to run ant when the build button is pressed, add a Shell Tool as
"Build#ant"
.
This tool is triggered, if present, from the toolbar Execute button. If you wanted to execute the program you are working on by clicking this button add a Shell Tool as
"Execute#cd build;myproggy"
.
MonkeyFish allows you to access the most frequently used tools of either svn or cvs. The app detects automatically the presence of either and pops up a relevant menu.
Currently you can:
Update
Commit
Status
Log
Add
Remove
Diff
At the moment there is no way to edit the SCM commands other then by editing the config file or the registry if you are on windows (see below). To do this, edit "$HOME/.MonkeyFish" in GTK or "$HOME/Library/Preferences/MonkeyFish Preferences" in os/x and examine the following lines...
[tools] svn.update=svn update %file% svn.commit=svn commit -F %tmpname% %file% svn.status=svn status %file% svn.log=svn log %file% svn.add=svn add %file% svn.remove=svn remove -F %tmpname% %file% svn.diff=svn diff %file% cvs.update=cvs update %file% cvs.commit=cvs commit -F %tmpname% %file% cvs.status=cvs status %file% cvs.log=cvs log %file% cvs.add=cvs add %file% cvs.remove=cvs remove -F %tmpname% %file% cvs.diff=cvs diff %file%
There are three variables that get replaced in your command.
%tmpname% is replaced by the temporary filename for comments. Comments are called from the commit and remove commands.
%file% is replaced by the full path to the file or directory. In the case of a file, the file name is included.
%path% is replaced by the path to the file or directory. In the case of a file, the file name is excluded.
For example, to change your setup to use Meld to examine diffs, change the relevant line in the config to "svn.diff=meld %path%".
If you have more detailed needs or are using another SCM system you can always add a Tool that will handle the job.
True to windows, MonkeyFish stores its settings in the registry rather then a text file. To edit these settings you need to go into the registry editor (regedit) and edit the tree beneath [HKEY_CURRENT_USER->Software->MonkeyFish]. You should be able to figure out the translation between the file based tree and the registry tree given the example above. In the future you will be able to edit these from the preferences dialog.
Type stuff. Run it. Make it type stuff.
MonkeyFish uses Lua for its scripting engine. Lua is a light-wieght programming language designed for extending applications. It combines a procedural syntax with a powerful data description constructs based on associative arrays and extensible semantics. It is dynamically typed and has automatic garbage collection.
Here is an example of a simple MonkeyFish script...
-- open a new file and get the editor object e = mf.new() -- insert some text into the editor e:insert("Welcome to MonkeyFish", 0 ) -- save the file to disk mf.save( "junk.txt" )
You can open a new editor and paste this text in. Then type Ctrl-Shift-E to execute it directly. There is no need to save it first.
You should read the documentation in the Lua manual in order to understand the power of the language. As an embedded language MonkeyFish offers some additional constructs that allow you to manipulate the environment.
These are some ideas and examples of the useage of scripting in the MonkeyFish environment.
One of the simplest things you can do with scripting is create templates for new files in your projects. If we are creating new HTML files all the time we can create some boiler-plate code quite easily that allows us to start with a common structure.
Go to
-> and create a new script called "xhtml.mf". The type the following in:text = [[ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Language" content="en-us" /> <meta name="ROBOTS" content="ALL" /> <meta name="Copyright" content="" /> <meta name="Keywords" content="" /> <meta name="Description" content="" /> <meta name="MSSmartTagsPreventParsing" content="true" /> <style type="text/css" media="all"> @import "master.css"; </style> <title></title> </head> <body> </body> </html> ]] e = mf.new() e:insert( text, 0 )
Now we can choose
-> and a new file is opened for us with this common structure.There are some globals available to your script from within the MonkeyFish scripting environment.
Table 4.1. Global Variables
Variable | Description | |
---|---|---|
LUA_PATH | Set to the scripts directory of your installation. | |
MF_OS | An integer representing the current platform. | |
MF_OS_DESC | Returns a string containing a description of the current platform. It may return string like "Window NT Version 4.0" or "Linux 2.2.2 i386". | |
mf | The MonkeyFish application itself expressed as a table. | |
Table 4.2. Global Functions
Function | Returns/Type | Description |
---|---|---|
getcwd() | string | Get the current workling directory. |
chdir("path") | nil on failure | Change the current working directory. |
tmpname() | string | Get a temporary file name. |
print("text") | nil | Prints text to the MonkeyFish output window. |
The mf table allows you to interact with the MonkeyFish enviroment itself.
Table 4.3. The mf table
Function | Returns | Description |
---|---|---|
mf.message("text" [,"title"]) | boolean (true if user picked ok or false if cancelled) | Popup a message box with the text. If the last character is a question mark '?' a question icon is used and the cancel button is shown. If the last character of msg is an exclamation mark '!' an error icon is used and the cancel button is shown. Otherwise, an information icon is used, only the OK button is shown. You can optionally add a title to the box. |
mf.gets("prompt"[,"title","default"]) | string or nil | Gets text from the user in a dialog box. Optionally "title" is the title on the box and "default" is the default input text. |
mf.getsml("prompt" [,"title","default"]) | string or nil | Gets a mutli-line text from the user in a dialog box. Optionally "title" is the title on the box and "default" is the default input text. |
mf.choice("item1 item2"[,"title","prompt"]) | string or nil | Allows the user to choose from a list of items. Optionally "title" is used as the title for the dialog and "prompt" is used as a prompt. |
mf.askdir(["prompt","defaultdir"]) | string or nil | Asks the user to choose a directory. |
mf.askfile("open|save"[,"prompt","defaultdir","defaultfile","wildcards"]) | string or nil | Asks the user to choose a file. An open or save dialog is shown depending on the first parameter. |
mf.askfiles(["prompt","defaultdir","defaultfile","wildcards"]) | table of filenames or nil | Ask the user to choose multiple files. |
mf.tabcount() | integer | Returns the number of open files. |
mf.open("filename") | editor object or nil | Opens a file in a new tab or if it is already open, selects that tab. |
mf.save("filename") | nil | Saves the current editor to "filename". |
mf.new() | editor object or nil | Opens an empty editor. |
mf.close( [bool] ) | bool (true if succesful) | Closes the current editor. If the arg bool is true (the default), the editor tries to save the file. If false, the editor is closed with the loss of data. |
mf.select(#) | nil | Select editor tab # |
mf.selected() | editor object or nil | Returns the selected editor |
mf.version() | string | MonkeyFish version string of the form "0.0.0" |
The editor object allows you to interact with the text in an edit buffer. The editor is zero based so the first position is 0 and the first line is 0.
Table 4.4. Editor Object
Function | Returns | Description |
---|---|---|
e:get() | string | Get the text from the editor. |
e:set("text") | bool | Sets the text in the editor to text. Erases the text currently in the editor. |
e:insert("text"[, pos ]) | integer (the inserted text length) | Inserts "text" at the pos, if given, or the current insertion point. |
e:delete(start, end) | integer (the length of text deleted) | Deletes the text between pos start and pos end. |
e:filename( ) | string: the current file path | Return the buffers file name. |
e:goto( pos ) | integer (the new position) or nil if invalid pos | Move caret to pos |
e:go( location ) | integer (the new position) or nil if invalid location |
Move caret to location. Location is a string with one of the
following:
|
e:gotoline( # ) | integer (the new line) or nil if invalid line | Move caret to line #. Line numbers are zero based. |
e:pos() | integer | Return the current position |
e:len() | integer | Length of the buffer in chars |
e:linecount() | integer | Number of lines in the buffer. |
e:line( lineno ) | string or nil if invalid lineno | Returns the line at lineno. Line numbers are zero based. |
e:select( pos1, pos2 ) | integer, the selection start position | Create a selection region from pos1 to pos2. If pos2 is negative then pos2 is set to the end of the buffer. If pos1 is negative then pos1 is set to the value of pos2: this will remove the selection. The caret will always be visible after this call. |
Table of Contents
This is a list of the known bugs/issues at the time this documentation was prepared. It at least contains the most serious known defects at the time of publication.