summary refs log tree commit diff stats
path: root/tools/nimrepl.nim
blob: 220307dba6b33145212bb0cf8e471f87c668af71 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-c
#
#
#              Nimrod REPL
#        (c) Copyright 2010 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("nimrod")
if nimExe.len == 0: nimExe = "../bin" / addFileExt("nimrod", os.exeExt)

proc execCode(code: string): string =
  var f: TFile
  if open(f, "temp.nim", fmWrite):
    f.write(code)
    f.close()
    result = osproc.execProcess(
      "$# $# --verbosity:0 --hint[Conf]:off temp.nim" % [nimExe, runCmd],
      {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: pgpointer){.cdecl.} = 
  main_quit()

proc FileOpenClicked(menuitem: PMenuItem, userdata: pgpointer) {.cdecl.} =
  var path = ChooseFileToOpen(w)
  if path != "":
    var file = readFile(path)
    if file != nil:
      set_text(InputTextBuffer, file, len(file))
    else:
      error(w, "Unable to read from file")

proc FileSaveClicked(menuitem: PMenuItem, userdata: pgpointer) {.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: TFile
  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: pgpointer): bool =
  if ($keyval_name(event.keyval)).tolower() == "shift_l":
    # SHIFT is pressed
    shiftPressed = True
  
proc setError(msg: string) = 
  outputTextBuffer.setText(msg, msg.len)
  
proc inputKeyReleased(widget: PWidget, event: PEventKey, 
                      userdata: pgpointer): bool =
  #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 shiftPressed == False:
      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))
      except EIO:
        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, "Nimrod 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 - Seperates 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)
  
nimrod_init()
initControls()
main()