mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			554 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			554 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
import "gtk" as gtk
 | 
						|
import "io" as io
 | 
						|
import "mgcollections" as collections
 | 
						|
import "button_factory" as button_factory
 | 
						|
import "dialog_factory" as dialog_factory
 | 
						|
import "syntax_highlighter" as highlighter
 | 
						|
import "auto_completer" as aComp
 | 
						|
 | 
						|
//TODO
 | 
						|
 | 
						|
// Autocomplete typing
 | 
						|
 | 
						|
// FileChooser
 | 
						|
// Themes
 | 
						|
 | 
						|
// Details for the Top Level Window
 | 
						|
def window = gtk.window(gtk.GTK_WINDOW_TOPLEVEL)
 | 
						|
window.title := "Grace"
 | 
						|
window.set_default_size(700, 700)
 | 
						|
// -------------
 | 
						|
 | 
						|
// Placeholder for the console window that can be popped out
 | 
						|
// of the main window
 | 
						|
var popped := gtk.window(gtk.GTK_WINDOW_TOPLEVEL)
 | 
						|
 | 
						|
// Initialise the Boxes
 | 
						|
def mBox = gtk.box(gtk.GTK_ORIENTATION_VERTICAL, 2)
 | 
						|
def buttonBox = gtk.box(gtk.GTK_ORIENTATION_HORIZONTAL, 2)
 | 
						|
var consoleButtons := gtk.box(gtk.GTK_ORIENTATION_HORIZONTAL, 3)
 | 
						|
var consoleBox := gtk.box(gtk.GTK_ORIENTATION_VERTICAL, 2)
 | 
						|
var editorBox := gtk.box(gtk.GTK_ORIENTATION_VERTICAL, 2)
 | 
						|
var splitPane := gtk.paned(gtk.GTK_ORIENTATION_VERTICAL, 2)
 | 
						|
def menuBox = gtk.box(gtk.GTK_ORIENTATION_HORIZONTAL, 4)
 | 
						|
// -------------
 | 
						|
 | 
						|
// Initialise the buttons
 | 
						|
def runButton = button_factory.make("run")
 | 
						|
var clearButton := button_factory.make("clear")
 | 
						|
var outButton := button_factory.make("out")
 | 
						|
var errorButton := button_factory.make("error")
 | 
						|
var popButton := button_factory.make("pop")
 | 
						|
def newButton = button_factory.make("new")
 | 
						|
def openButton = button_factory.make("open")
 | 
						|
def saveButton = button_factory.make("save")
 | 
						|
def saveAsButton = button_factory.make("saveAs")
 | 
						|
def closeButton = button_factory.make("close")
 | 
						|
// -------------
 | 
						|
 | 
						|
// Details for the default text editor and scrolled window
 | 
						|
var tEdit := gtk.text_view
 | 
						|
tEdit.set_size_request(700, 400)
 | 
						|
 | 
						|
var scrolled_main := gtk.scrolled_window
 | 
						|
scrolled_main.set_size_request(700, 400)
 | 
						|
scrolled_main.add(tEdit)
 | 
						|
// -------------
 | 
						|
 | 
						|
// Widget that allows multiple files to be edited (tabs)
 | 
						|
var notebook := gtk.notebook
 | 
						|
notebook.scrollable := true
 | 
						|
// -------------
 | 
						|
 | 
						|
// Maps for holding the text_views and scrolled_windows
 | 
						|
var editor_map := collections.map.new
 | 
						|
editor_map.put(0, tEdit)
 | 
						|
var scrolled_map := collections.map.new
 | 
						|
scrolled_map.put(0, scrolled_main)
 | 
						|
 | 
						|
// -------------
 | 
						|
 | 
						|
// Class that manages the syntax highlighting (This needs to be passed around otherwise
 | 
						|
// the text_tag table gets confused, ie there can only be one)
 | 
						|
def lighter = highlighter.Syntax_Highlighter.new(notebook, editor_map)
 | 
						|
tEdit.buffer.on "changed" do {
 | 
						|
    lighter.highlightLine
 | 
						|
}
 | 
						|
 | 
						|
// Class that manages any auto completion that is required
 | 
						|
def completer =  aComp.Auto_Completer.new(window, notebook, editor_map)
 | 
						|
 | 
						|
// Utility methods
 | 
						|
// -------------
 | 
						|
 | 
						|
method deleteCompileFiles(page_num : Number) {
 | 
						|
    def cur_scrolled = scrolled_map.get(page_num)
 | 
						|
    var filename := notebook.get_tab_label_text(cur_scrolled)
 | 
						|
    filename := filename.substringFrom(0)to(filename.size - 7) //Removes .grace extension
 | 
						|
 | 
						|
    io.system("rm -f files/" ++ filename)
 | 
						|
    io.system("rm -f files/" ++ filename ++ ".c")
 | 
						|
    io.system("rm -f files/" ++ filename ++ ".gcn")
 | 
						|
    io.system("rm -f files/" ++ filename ++ ".gct")
 | 
						|
}
 | 
						|
 | 
						|
// -------------
 | 
						|
 | 
						|
 | 
						|
 | 
						|
var currentConsole := "output"      // Which console is being shown
 | 
						|
var out := false
 | 
						|
 | 
						|
 | 
						|
var outText := ""
 | 
						|
var errorText := ""
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// Give actions to the buttons
 | 
						|
// -------------
 | 
						|
 | 
						|
runButton.on "clicked" do {
 | 
						|
    clearConsoles()
 | 
						|
 | 
						|
    // Get the details for the current page selected
 | 
						|
    def cur_page_num = notebook.current_page
 | 
						|
    def cur_page = editor_map.get(cur_page_num)
 | 
						|
    def cur_scrolled = scrolled_map.get(cur_page_num)
 | 
						|
    def cur_page_label = notebook.get_tab_label_text(cur_scrolled)
 | 
						|
 | 
						|
    // Initialise text iterators
 | 
						|
    def sIter = gtk.text_iter
 | 
						|
    def eIter = gtk.text_iter
 | 
						|
 | 
						|
    // Set one at the beggining and one at the end of the text
 | 
						|
    cur_page.buffer.get_iter_at_offset(sIter, 0)
 | 
						|
    cur_page.buffer.get_iter_at_offset(eIter, -1)
 | 
						|
 | 
						|
    // Get the text between the text iterators
 | 
						|
    def text = cur_page.buffer.get_text(sIter, eIter, true)
 | 
						|
 | 
						|
    // Save the text to the file (in case the user hasn't already saved it)
 | 
						|
    def file = io.open("files/" ++ cur_page_label, "w")
 | 
						|
    file.write(text)
 | 
						|
    file.close
 | 
						|
 | 
						|
    // Run the program and pipe the output and errors into files to be read
 | 
						|
    io.system("../minigrace/minigrace " ++ "files/" ++ cur_page_label ++ " > output.txt 2> error.txt")
 | 
						|
    def outputFile = io.open("output.txt", "r")
 | 
						|
    def errorFile = io.open("error.txt", "r")
 | 
						|
    outText := outputFile.read
 | 
						|
    errorText := errorFile.read
 | 
						|
 | 
						|
    io.system("rm -f output.txt error.txt")
 | 
						|
 | 
						|
    var switched := false
 | 
						|
 | 
						|
    // Change the console to output if there is output text
 | 
						|
    if((outText.size > 0) && (currentConsole != "output")) then {
 | 
						|
        switch_to_output()
 | 
						|
        switched := true
 | 
						|
    }
 | 
						|
    // Change the console to errors if there were errors
 | 
						|
    if((errorText.size > 0) && (currentConsole != "errors")) then {
 | 
						|
        switch_to_errors()
 | 
						|
        switched := true
 | 
						|
    }
 | 
						|
 | 
						|
    // Remember to populate the console if it wasn't switched
 | 
						|
    if(!switched) then {
 | 
						|
        populateConsoles
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
clearButton.on "clicked" do {
 | 
						|
    clearConsoles()
 | 
						|
}
 | 
						|
 | 
						|
outButton.on "clicked" do {
 | 
						|
    switch_to_output()
 | 
						|
}
 | 
						|
 | 
						|
errorButton.on "clicked" do {
 | 
						|
    switch_to_errors()
 | 
						|
}
 | 
						|
 | 
						|
popButton.on "clicked" do {
 | 
						|
    if(out) then {
 | 
						|
        popIn()
 | 
						|
    } else {
 | 
						|
        popOut()
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
// Gives a dialog to let the user create a new file to edit
 | 
						|
newButton.on "clicked" do {
 | 
						|
    def new_window_class = dialog_factory.new.new(notebook, editor_map, scrolled_map, lighter)
 | 
						|
 | 
						|
    def new_window = new_window_class.window()
 | 
						|
    new_window.show_all
 | 
						|
}
 | 
						|
 | 
						|
// Gives a dialog that lets the user open a file to edit
 | 
						|
openButton.on "clicked" do {
 | 
						|
    def open_window_class = dialog_factory.open.new(notebook, editor_map, scrolled_map, lighter)
 | 
						|
 | 
						|
    def open_window = open_window_class.window()
 | 
						|
    open_window.show_all
 | 
						|
}
 | 
						|
 | 
						|
// Saves the current file (if the name is Untitled.grace it will ask for a new name)
 | 
						|
saveButton.on "clicked" do {
 | 
						|
    def cur_page_num = notebook.current_page
 | 
						|
    def cur_page = editor_map.get(cur_page_num)
 | 
						|
    def cur_scrolled = scrolled_map.get(cur_page_num)
 | 
						|
    def cur_page_label = notebook.get_tab_label_text(cur_scrolled)
 | 
						|
 | 
						|
    if(cur_page_label == "Untitled.grace") then {
 | 
						|
        def saveAs_window_class = dialog_factory.save.new(notebook, editor_map, scrolled_map, true)
 | 
						|
 | 
						|
        def saveAs_window = saveAs_window_class.window()
 | 
						|
        saveAs_window.show_all
 | 
						|
    } else {
 | 
						|
        // Initialise text iterators
 | 
						|
        def sIter = gtk.text_iter
 | 
						|
        def eIter = gtk.text_iter
 | 
						|
 | 
						|
        // Set one at the beggining and one at the end of the text
 | 
						|
        cur_page.buffer.get_iter_at_offset(sIter, 0)
 | 
						|
        cur_page.buffer.get_iter_at_offset(eIter, -1)
 | 
						|
 | 
						|
        // Get the text between the text iterators
 | 
						|
        def text = cur_page.buffer.get_text(sIter, eIter, true)
 | 
						|
 | 
						|
        // Save the file
 | 
						|
        def file = io.open("files/" ++ cur_page_label, "w")
 | 
						|
        file.write(text)
 | 
						|
        file.close
 | 
						|
    }
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
// Gives a dialog that lets the user save the file with a new name
 | 
						|
saveAsButton.on "clicked" do {
 | 
						|
    def saveAs_window_class = dialog_factory.save.new(notebook, editor_map, scrolled_map, false)
 | 
						|
 | 
						|
    def saveAs_window = saveAs_window_class.window()
 | 
						|
    saveAs_window.show_all
 | 
						|
}
 | 
						|
 | 
						|
// This will close a tab on the notebook
 | 
						|
// It also "removes" the page from the map,
 | 
						|
// by creating a new temporary map and putting all but
 | 
						|
// the removed page in.
 | 
						|
closeButton.on "clicked" do {
 | 
						|
    def page_num = notebook.current_page
 | 
						|
    def num_pages = notebook.n_pages
 | 
						|
 | 
						|
    if(num_pages > 1) then {
 | 
						|
        deleteCompileFiles(page_num)
 | 
						|
 | 
						|
        def e_map = collections.map.new
 | 
						|
        def s_map = collections.map.new
 | 
						|
 | 
						|
        // Copy every page up to the current page into the new maps
 | 
						|
        var x := 0
 | 
						|
        while {x < page_num} do {
 | 
						|
            var eValue := editor_map.get(x)
 | 
						|
            var sValue := scrolled_map.get(x)
 | 
						|
            e_map.put(x, eValue)
 | 
						|
            s_map.put(x, sValue)
 | 
						|
 | 
						|
            x := x + 1
 | 
						|
        }
 | 
						|
 | 
						|
        // Copy every page after the current page into the new map (shifted one down)
 | 
						|
        x := page_num + 1
 | 
						|
        while {x < num_pages} do {
 | 
						|
            var eValue := editor_map.get(x)
 | 
						|
            var sValue := scrolled_map.get(x)
 | 
						|
            e_map.put((x - 1), eValue)
 | 
						|
            s_map.put((x - 1), sValue)
 | 
						|
 | 
						|
            x := x + 1
 | 
						|
        }
 | 
						|
 | 
						|
        editor_map := e_map
 | 
						|
        scrolled_map := s_map
 | 
						|
        notebook.remove_page(page_num)
 | 
						|
 | 
						|
        notebook.show_all
 | 
						|
    }
 | 
						|
 | 
						|
}
 | 
						|
// -------------
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// Consoles:
 | 
						|
// -------------
 | 
						|
 | 
						|
var outConsole := gtk.text_view
 | 
						|
var outScroll := gtk.scrolled_window
 | 
						|
var errorConsole := gtk.text_view
 | 
						|
var errorScroll := gtk.scrolled_window
 | 
						|
var errorTag := errorConsole.buffer.create_tag("fixed", "foreground", "red")
 | 
						|
 | 
						|
 | 
						|
// Creates a new output console
 | 
						|
method createOut {
 | 
						|
    outConsole := gtk.text_view
 | 
						|
    outScroll := gtk.scrolled_window
 | 
						|
    outScroll.add(outConsole)
 | 
						|
    if(out) then {
 | 
						|
        outConsole.set_size_request(400, 400)
 | 
						|
        outScroll.set_size_request(400, 400)
 | 
						|
    } else {
 | 
						|
        outConsole.set_size_request(700, 200)
 | 
						|
        outScroll.set_size_request(700, 200)
 | 
						|
    }
 | 
						|
    outConsole.editable := false
 | 
						|
    outConsole.buffer.set_text("[Output]:", -1)
 | 
						|
}
 | 
						|
createOut()
 | 
						|
 | 
						|
// Creates a new error console
 | 
						|
method createError {
 | 
						|
    errorConsole := gtk.text_view
 | 
						|
    errorScroll := gtk.scrolled_window
 | 
						|
    errorScroll.add(errorConsole)
 | 
						|
    if(out) then {
 | 
						|
        errorConsole.set_size_request(400, 400)
 | 
						|
        errorScroll.set_size_request(400, 400)
 | 
						|
    } else {
 | 
						|
        errorConsole.set_size_request(700, 200)
 | 
						|
        errorScroll.set_size_request(700, 200)
 | 
						|
    }
 | 
						|
    errorConsole.editable := false
 | 
						|
    errorConsole.buffer.set_text("[Errors]:", -1)
 | 
						|
    errorTag := errorConsole.buffer.create_tag("fixed", "foreground", "red")
 | 
						|
}
 | 
						|
createError()
 | 
						|
 | 
						|
// Switches the console being shown to be output. This requires
 | 
						|
// the output console to be remade as it would have been destroyed when
 | 
						|
// it was switched previously
 | 
						|
method switch_to_output {
 | 
						|
    if(currentConsole != "output") then {
 | 
						|
        currentConsole := "output"
 | 
						|
        consoleBox.remove(errorScroll)     // This destroys the errorConsole
 | 
						|
 | 
						|
        createOut()
 | 
						|
 | 
						|
        consoleBox.add(outScroll)
 | 
						|
 | 
						|
        populateConsoles()
 | 
						|
        if(out) then {
 | 
						|
            popped.show_all
 | 
						|
        } else {
 | 
						|
            window.show_all
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
// Switches the console being shown to be errors. This requires
 | 
						|
// the error console to be remade as it would have been destroyed when
 | 
						|
// it was switched previously
 | 
						|
method switch_to_errors {
 | 
						|
    if(currentConsole != "errors") then {
 | 
						|
        currentConsole := "errors"
 | 
						|
        consoleBox.remove(outScroll)       // This destroys the outConsole
 | 
						|
 | 
						|
        createError()
 | 
						|
 | 
						|
        consoleBox.add(errorScroll)
 | 
						|
 | 
						|
        populateConsoles()
 | 
						|
        if(out) then {
 | 
						|
            popped.show_all
 | 
						|
        } else {
 | 
						|
            window.show_all
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
// If there is text to be put into the consoles this will add it
 | 
						|
method populateConsoles {
 | 
						|
    if((outText.size > 0) && (currentConsole == "output")) then {
 | 
						|
        outConsole.buffer.set_text(outText, -1)
 | 
						|
    }
 | 
						|
    if((errorText.size > 0) && (currentConsole == "errors")) then {
 | 
						|
        def sIter = gtk.text_iter
 | 
						|
        def eIter = gtk.text_iter
 | 
						|
 | 
						|
        errorConsole.buffer.set_text(errorText, -1)
 | 
						|
        errorConsole.buffer.get_iter_at_offset(sIter, 0)
 | 
						|
        errorConsole.buffer.get_iter_at_offset(eIter, -1)
 | 
						|
        errorConsole.buffer.apply_tag(errorTag, sIter, eIter)
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
method clearConsoles {
 | 
						|
    if(currentConsole == "output") then {
 | 
						|
        outConsole.buffer.set_text("[Output]:", -1)
 | 
						|
        outText := ""
 | 
						|
    }
 | 
						|
    if(currentConsole == "errors") then {
 | 
						|
        errorConsole.buffer.set_text("[Errors]:", -1)
 | 
						|
        errorText := ""
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Identical as the popIn method, but can be connected to the window's destroy button
 | 
						|
def popInBlock = {
 | 
						|
    consoleBox.reparent(splitPane)
 | 
						|
    popButton.label := "Pop Out"
 | 
						|
 | 
						|
    if(currentConsole == "output") then {
 | 
						|
        outConsole.set_size_request(700, 200)
 | 
						|
        outScroll.set_size_request(700, 200)
 | 
						|
    }
 | 
						|
    if(currentConsole == "errors") then {
 | 
						|
     errorConsole.set_size_request(700, 200)
 | 
						|
     errorScroll.set_size_request(700, 200)
 | 
						|
    }
 | 
						|
 | 
						|
    def cur_page_num = notebook.current_page
 | 
						|
    def cur_scrolled = scrolled_map.get(cur_page_num)
 | 
						|
    def cur_page = editor_map.get(cur_page_num)
 | 
						|
 | 
						|
    cur_page.set_size_request(700, 400)
 | 
						|
    cur_scrolled.set_size_request(700, 400)
 | 
						|
 | 
						|
    out := false
 | 
						|
    popped.visible := false
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// This pops the console out into a separate window
 | 
						|
method popOut {
 | 
						|
    popped := gtk.window(gtk.GTK_WINDOW_TOPLEVEL)
 | 
						|
 | 
						|
    consoleBox.reparent(popped)
 | 
						|
    popButton.label := "Pop In"
 | 
						|
 | 
						|
    if(currentConsole == "output") then {
 | 
						|
        outConsole.set_size_request(400, 400)
 | 
						|
        outScroll.set_size_request(400, 400)
 | 
						|
    }
 | 
						|
    if(currentConsole == "errors") then {
 | 
						|
        errorConsole.set_size_request(400, 400)
 | 
						|
        errorScroll.set_size_request(400, 400)
 | 
						|
    }
 | 
						|
 | 
						|
    def cur_page_num = notebook.current_page
 | 
						|
    def cur_scrolled = scrolled_map.get(cur_page_num)
 | 
						|
    def cur_page = editor_map.get(cur_page_num)
 | 
						|
 | 
						|
    cur_page.set_size_request(700, 580)
 | 
						|
    cur_scrolled.set_size_request(700, 580)
 | 
						|
 | 
						|
    out := true
 | 
						|
    popped.visible := true
 | 
						|
    popped.connect("destroy", popInBlock)
 | 
						|
    popped.show_all
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
// Puts the console back into the main window
 | 
						|
method popIn {
 | 
						|
    consoleBox.reparent(splitPane)
 | 
						|
    popButton.label := "Pop Out"
 | 
						|
 | 
						|
    if(currentConsole == "output") then {
 | 
						|
        outConsole.set_size_request(700, 200)
 | 
						|
        outScroll.set_size_request(700, 200)
 | 
						|
    }
 | 
						|
    if(currentConsole == "errors") then {
 | 
						|
        errorConsole.set_size_request(700, 200)
 | 
						|
        errorScroll.set_size_request(700, 200)
 | 
						|
    }
 | 
						|
 | 
						|
    def cur_page_num = notebook.current_page
 | 
						|
    def cur_scrolled = scrolled_map.get(cur_page_num)
 | 
						|
    def cur_page = editor_map.get(cur_page_num)
 | 
						|
 | 
						|
    cur_page.set_size_request(700, 400)
 | 
						|
    cur_scrolled.set_size_request(700, 400)
 | 
						|
 | 
						|
    out := false
 | 
						|
    popped.visible := false
 | 
						|
}
 | 
						|
 | 
						|
clearConsoles()
 | 
						|
// -------------
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// Patch everything together
 | 
						|
 | 
						|
var hSeparator1 := gtk.separator(gtk.GTK_ORIENTATION_HORIZONTAL)
 | 
						|
var hSeparator2 := gtk.separator(gtk.GTK_ORIENTATION_HORIZONTAL)
 | 
						|
 | 
						|
menuBox.add(newButton)
 | 
						|
menuBox.add(openButton)
 | 
						|
menuBox.add(saveButton)
 | 
						|
menuBox.add(saveAsButton)
 | 
						|
buttonBox.add(runButton)
 | 
						|
buttonBox.add(closeButton)
 | 
						|
 | 
						|
consoleButtons.add(outButton)
 | 
						|
consoleButtons.add(errorButton)
 | 
						|
consoleButtons.add(clearButton)
 | 
						|
consoleButtons.add(popButton)
 | 
						|
 | 
						|
consoleBox.add(hSeparator1)
 | 
						|
consoleBox.add(consoleButtons)
 | 
						|
consoleBox.add(outScroll)
 | 
						|
 | 
						|
editorBox.add(hSeparator2)
 | 
						|
notebook.add(scrolled_main)
 | 
						|
notebook.set_tab_label_text(scrolled_main, "Untitled.grace")
 | 
						|
editorBox.add(notebook)
 | 
						|
 | 
						|
splitPane.add1(editorBox)
 | 
						|
splitPane.add2(consoleBox)
 | 
						|
 | 
						|
mBox.add(menuBox)
 | 
						|
mBox.add(buttonBox)
 | 
						|
mBox.add(splitPane)
 | 
						|
 | 
						|
window.add(mBox)
 | 
						|
 | 
						|
def exit = {
 | 
						|
    var x := 0
 | 
						|
    while {x < notebook.n_pages} do {
 | 
						|
        deleteCompileFiles(x)
 | 
						|
 | 
						|
        x := x + 1
 | 
						|
    }
 | 
						|
 | 
						|
    // Delete the compile files of the IDE
 | 
						|
    io.system("rm -f Grace_IDE.gct Grace_IDE.c Grace_IDE.gcn")
 | 
						|
    io.system("rm -f scanner.gct scanner.c scanner.gcn")
 | 
						|
    io.system("rm -f syntax_highlighter.gct syntax_highlighter.c syntax_highlighter.gcn")
 | 
						|
    io.system("rm -f syntax_colors.gct syntax_colors.c syntax_colors.gcn")
 | 
						|
    io.system("rm -f button_factory.gct button_factory.c button_factory.gcn")
 | 
						|
    io.system("rm -f dialog_factory.gct dialog_factory.c dialog_factory.gcn")
 | 
						|
    io.system("rm -f auto_completer.gct auto_completer.c auto_completer.gcn")
 | 
						|
 | 
						|
    print "Grace IDE Closed Successfully"
 | 
						|
    gtk.main_quit
 | 
						|
}
 | 
						|
 | 
						|
window.connect("destroy", exit)
 | 
						|
window.show_all
 | 
						|
 | 
						|
gtk.main |