# # # Nim REPL # (c) Copyright 2012 Dominik Picheta # # See the file "copying.txt", included in this # distribution, for details about the copyright. # import glib2, gtk2, gdk2, os, osproc, dialogs, strutils when defined(tinyc): const runCmd = "run" else: const runCmd = "c -r" var nimExe = findExe("nim") if nimExe.len == 0: nimExe = "../bin" / addFileExt("nim", os.ExeExt) proc execCode(code: string): string = var f: File if open(f, "temp.nim", fmWrite): f.write(code) f.close() result = osproc.execProcess( "$# $# --verbosity:0 --hint[Conf]:off temp.nim" % [nimExe, runCmd], options = {poStdErrToStdOut}) else: result = "cannot open file 'temp.nim'" var shiftPressed = false var w: gtk2.PWindow var inputTextBuffer: PTextBuffer var outputTextBuffer: PTextBuffer proc destroy(widget: PWidget, data: pointer){.cdecl.} = main_quit() proc fileOpenClicked(menuitem: PMenuItem, userdata: pointer) {.cdecl.} = var path = chooseFileToOpen(w) if path != "": var file = readFile(path) if file != nil: set_text(inputTextBuffer, file, len(file).gint) else: error(w, "Unable to read from file") proc fileSaveClicked(menuitem: PMenuItem, userdata: pointer) {.cdecl.} = var path = chooseFileToSave(w) if path == "": return var startIter: TTextIter var endIter: TTextIter get_start_iter(inputTextBuffer, addr(startIter)) get_end_iter(inputTextBuffer, addr(endIter)) var inputText = get_text(inputTextBuffer, addr(startIter), addr(endIter), false) var f: File if open(f, path, fmWrite): f.write(inputText) f.close() else: error(w, "Unable to write to file") proc inputKeyPressed(widget: PWidget, event: PEventKey, userdata: pointer): bool {.cdecl.} = if ($keyval_name(event.keyval)).tolower() == "shift_l": # SHIFT is pressed shiftPressed = true proc setError(msg: string) = outputTextBuffer.setText(msg, msg.len.gint) proc inputKeyReleased(widget: PWidget, event: PEventKey, userdata: pointer): bool {.cdecl.} = #echo(keyval_name(event.keyval)) if ($keyval_name(event.keyval)).tolower() == "shift_l": # SHIFT is released shiftPressed = false if ($keyval_name(event.keyval)).tolower() == "return": #echo($keyval_name(event.keyval), "Shift_L") # Enter pressed if not shiftPressed: var startIter: TTextIter var endIter: TTextIter get_start_iter(inputTextBuffer, addr(startIter)) get_end_iter(inputTextBuffer, addr(endIter)) var inputText = get_text(inputTextBuffer, addr(startIter), addr(endIter), false) try: var r = execCode($inputText) set_text(outputTextBuffer, r, len(r).gint) except IOError: setError("Error: Could not open file temp.nim") proc initControls() = w = window_new(gtk2.WINDOW_TOPLEVEL) set_default_size(w, 500, 600) set_title(w, "Nim REPL") discard signal_connect(w, "destroy", SIGNAL_FUNC(nimrepl.destroy), nil) # MainBox (vbox) var mainBox = vbox_new(false, 0) add(w, mainBox) # TopMenu (MenuBar) var topMenu = menu_bar_new() show(topMenu) var fileMenu = menu_new() var openMenuItem = menu_item_new("Open") append(fileMenu, openMenuItem) show(openMenuItem) discard signal_connect(openMenuItem, "activate", SIGNAL_FUNC(fileOpenClicked), nil) var saveMenuItem = menu_item_new("Save...") append(fileMenu, saveMenuItem) show(saveMenuItem) discard signal_connect(saveMenuItem, "activate", SIGNAL_FUNC(fileSaveClicked), nil) var fileMenuItem = menu_item_new("File") set_submenu(fileMenuItem, fileMenu) show(fileMenuItem) append(topMenu, fileMenuItem) pack_start(mainBox, topMenu, false, false, 0) # VPaned - Separates the InputTextView and the OutputTextView var paned = vpaned_new() set_position(paned, 450) pack_start(mainBox, paned, true, true, 0) show(paned) # Init the TextBuffers inputTextBuffer = text_buffer_new(nil) outputTextBuffer = text_buffer_new(nil) # InputTextView (TextView) var inputScrolledWindow = scrolled_window_new(nil, nil) set_policy(inputScrolledWindow, POLICY_AUTOMATIC, POLICY_AUTOMATIC) var inputTextView = text_view_new(inputTextBuffer) add_with_viewport(inputScrolledWindow, inputTextView) add1(paned, inputScrolledWindow) show(inputScrolledWindow) show(inputTextView) discard signal_connect(inputTextView, "key-release-event", SIGNAL_FUNC(inputKeyReleased), nil) discard signal_connect(inputTextView, "key-press-event", SIGNAL_FUNC(inputKeyPressed), nil) # OutputTextView (TextView) var outputScrolledWindow = scrolled_window_new(nil, nil) set_policy(outputScrolledWindow, POLICY_AUTOMATIC, POLICY_AUTOMATIC) var outputTextView = text_view_new(outputTextBuffer) add_with_viewport(outputScrolledWindow, outputTextView) add2(paned, outputScrolledWindow) show(outputScrolledWindow) show(outputTextView) show(w) show(mainBox) nim_init() initControls() main()