<commit_before>url = require('url')
Repl = require('./repl')
{$, Range} = require 'atom'


module.exports =
class Controller

  constructor: (@workspaceView, directory) ->
    @defaultURI = "sclang://localhost:57120"
    @projectRoot = if directory then directory.path else ''
    @repls = {}
    @activeRepl = null
    @markers = []

  start: ->
    @workspaceView.command "supercollider:open-post-window", =>
      @openPostWindow(@defaultURI)
    @workspaceView.command "supercollider:clear-post-window", =>
      @clearPostWindow()
    @workspaceView.command "supercollider:recompile", =>
      @recompile()
    @workspaceView.command "supercollider:cmd-period", =>
      @cmdPeriod()
    @workspaceView.command "supercollider:eval", =>
      @eval()
    @workspaceView.command "supercollider:open-help-file", =>
      @openHelpFile()

    # open a REPL for sclang on this host/port
    atom.workspace.registerOpener (uri) =>
      try
        {protocol, hostname, port} = url.parse(uri)
      catch error
        return
      return unless protocol is 'sclang:'

      onClose = =>
        if @activeRepl is repl
          @destroyRepl()
        delete @repls[uri]

      repl = new Repl(uri, @projectRoot, onClose)
      @activateRepl repl
      @repls[uri] = repl
      window = repl.createPostWindow()
      repl.startSCLang()
      window

  stop: ->
    for repl in @repls
      repl.stop()
    @destroyRepl()
    @repls = {}

  activateRepl: (repl) ->
    @activeRepl = repl
    @activeRepl.unsubscriber = repl.emit.subscribe (event) =>
      @handleReplEvent(event)

  destroyRepl: () ->
    @activeRepl?.unsubscriber()
    @activeRepl = null

  handleReplEvent: (event) ->
    error = event.value()
    # only expecting compile errors for now
    if error.index == 0
      @openToSyntaxError(error.file, error.line, error.char)

  openPostWindow: (uri) ->
    repl = @repls[uri]

    if repl
      @activateRepl repl
    else
      # open links on click
      fileOpener = (event) =>

        # A or child of A
        link = event.target.href
        unless link
          link = $(event.target).parents('a').attr('href')

        return unless link

        event.preventDefault()

        if link.substr(0, 7) == 'file://'
          path = link.substr(7)
          atom.workspace.open(path, split: 'left', searchAllPanes: true)
          return

        if link.substr(0, 10) == 'scclass://'
          link = link.substr(10)
          [path, charPos] = link.split(':')
          if ',' in charPos
            [lineno, char] = charPos.split(',')
            @openFile(
              path,
              null,
              parseInt(lineno),
              parseInt(char),
              'line',
              'line-highlight')
          else
            @openFile(
              path,
              parseInt(charPos),
              null,
              null,
              'line',
              'line-highlight')

      atom.workspace.open(uri, split: 'right', searchAllPanes: true)
        .then () =>
          @activateRepl @repls[uri]
          $('.post-window').on 'click', fileOpener

  clearPostWindow: ->
    @activeRepl?.clearPostWindow()

  recompile: ->
    @destroyMarkers()
    if @activeRepl
      @activeRepl.recompile()
    else
      @openPostWindow(@defaultURI)

  cmdPeriod: ->
    @activeRepl?.cmdPeriod()

  editorIsSC: ->
    editor = atom.workspace.getActiveEditor()
    editor and editor.getGrammar().scopeName is 'source.supercollider'

  currentExpression: ->
    editor = atom.workspace.getActiveEditor()
    return unless editor?

    selection = editor.getLastSelection()
    expression = selection.getText()
    if expression
      range = selection.getBufferRange()
    else
      # execute the line you are on
      pos = editor.getCursorBufferPosition()
      row = editor.getCursorScreenRow()
      if row?
        range = new Range([row, 0], [row + 1, 0])
        expression = editor.lineForBufferRow(row)
      else
        range = null
        expression = null
    [expression, range]

  currentPath: ->
    editor = atom.workspace.getActiveEditor()
    return unless editor?
    editor.getPath()

  eval: ->
    return unless @editorIsSC()
    [expression, range] = @currentExpression()
    @evalWithRepl(expression, @currentPath(), range)

  evalWithRepl: (expression, path, range) ->
    @destroyMarkers()

    return unless expression

    doIt = () =>
      if range?
        unflash = @evalFlash(range)

      onSuccess = () ->
        unflash?('eval-success')

      onError = (error) =>
        if error.type is 'SyntaxError'
          unflash?('eval-syntax-error')
          if path
            # offset syntax error by position of selected text in file
            row = range.getRows()[0] + error.error.syntaxErrors.line
            col = error.error.syntaxErrors.charPos
            @openToSyntaxError(path, parseInt(row), parseInt(col))
        else
          # runtime error
          unflash?('eval-error')

      @activeRepl.eval(expression, false, path)
        .then(onSuccess, onError)

    if @activeRepl
      @activeRepl.warnIsNotCompiled()
      # if stuck in compile error
      # then post warning and return
      unless @activeRepl.isCompiled()
        @activeRepl.warnIsNotCompiled()
        return
      doIt()
    else
      @openPostWindow(@defaultURI)
        .then doIt

  openToSyntaxError: (path, line, char) ->
    @openFile(path, null, line, char)
<commit_msg>doh, remove debugging<commit_after>url = require('url')
Repl = require('./repl')
{$, Range} = require 'atom'


module.exports =
class Controller

  constructor: (@workspaceView, directory) ->
    @defaultURI = "sclang://localhost:57120"
    @projectRoot = if directory then directory.path else ''
    @repls = {}
    @activeRepl = null
    @markers = []

  start: ->
    @workspaceView.command "supercollider:open-post-window", =>
      @openPostWindow(@defaultURI)
    @workspaceView.command "supercollider:clear-post-window", =>
      @clearPostWindow()
    @workspaceView.command "supercollider:recompile", =>
      @recompile()
    @workspaceView.command "supercollider:cmd-period", =>
      @cmdPeriod()
    @workspaceView.command "supercollider:eval", =>
      @eval()
    @workspaceView.command "supercollider:open-help-file", =>
      @openHelpFile()

    # open a REPL for sclang on this host/port
    atom.workspace.registerOpener (uri) =>
      try
        {protocol, hostname, port} = url.parse(uri)
      catch error
        return
      return unless protocol is 'sclang:'

      onClose = =>
        if @activeRepl is repl
          @destroyRepl()
        delete @repls[uri]

      repl = new Repl(uri, @projectRoot, onClose)
      @activateRepl repl
      @repls[uri] = repl
      window = repl.createPostWindow()
      repl.startSCLang()
      window

  stop: ->
    for repl in @repls
      repl.stop()
    @destroyRepl()
    @repls = {}

  activateRepl: (repl) ->
    @activeRepl = repl
    @activeRepl.unsubscriber = repl.emit.subscribe (event) =>
      @handleReplEvent(event)

  destroyRepl: () ->
    @activeRepl?.unsubscriber()
    @activeRepl = null

  handleReplEvent: (event) ->
    error = event.value()
    # only expecting compile errors for now
    if error.index == 0
      @openToSyntaxError(error.file, error.line, error.char)

  openPostWindow: (uri) ->
    repl = @repls[uri]

    if repl
      @activateRepl repl
    else
      # open links on click
      fileOpener = (event) =>

        # A or child of A
        link = event.target.href
        unless link
          link = $(event.target).parents('a').attr('href')

        return unless link

        event.preventDefault()

        if link.substr(0, 7) == 'file://'
          path = link.substr(7)
          atom.workspace.open(path, split: 'left', searchAllPanes: true)
          return

        if link.substr(0, 10) == 'scclass://'
          link = link.substr(10)
          [path, charPos] = link.split(':')
          if ',' in charPos
            [lineno, char] = charPos.split(',')
            @openFile(
              path,
              null,
              parseInt(lineno),
              parseInt(char),
              'line',
              'line-highlight')
          else
            @openFile(
              path,
              parseInt(charPos),
              null,
              null,
              'line',
              'line-highlight')

      atom.workspace.open(uri, split: 'right', searchAllPanes: true)
        .then () =>
          @activateRepl @repls[uri]
          $('.post-window').on 'click', fileOpener

  clearPostWindow: ->
    @activeRepl?.clearPostWindow()

  recompile: ->
    @destroyMarkers()
    if @activeRepl
      @activeRepl.recompile()
    else
      @openPostWindow(@defaultURI)

  cmdPeriod: ->
    @activeRepl?.cmdPeriod()

  editorIsSC: ->
    editor = atom.workspace.getActiveEditor()
    editor and editor.getGrammar().scopeName is 'source.supercollider'

  currentExpression: ->
    editor = atom.workspace.getActiveEditor()
    return unless editor?

    selection = editor.getLastSelection()
    expression = selection.getText()
    if expression
      range = selection.getBufferRange()
    else
      # execute the line you are on
      pos = editor.getCursorBufferPosition()
      row = editor.getCursorScreenRow()
      if row?
        range = new Range([row, 0], [row + 1, 0])
        expression = editor.lineForBufferRow(row)
      else
        range = null
        expression = null
    [expression, range]

  currentPath: ->
    editor = atom.workspace.getActiveEditor()
    return unless editor?
    editor.getPath()

  eval: ->
    return unless @editorIsSC()
    [expression, range] = @currentExpression()
    @evalWithRepl(expression, @currentPath(), range)

  evalWithRepl: (expression, path, range) ->
    @destroyMarkers()

    return unless expression

    doIt = () =>
      if range?
        unflash = @evalFlash(range)

      onSuccess = () ->
        unflash?('eval-success')

      onError = (error) =>
        if error.type is 'SyntaxError'
          unflash?('eval-syntax-error')
          if path
            # offset syntax error by position of selected text in file
            row = range.getRows()[0] + error.error.syntaxErrors.line
            col = error.error.syntaxErrors.charPos
            @openToSyntaxError(path, parseInt(row), parseInt(col))
        else
          # runtime error
          unflash?('eval-error')

      @activeRepl.eval(expression, false, path)
        .then(onSuccess, onError)

    if @activeRepl
      # if stuck in compile error
      # then post warning and return
      unless @activeRepl.isCompiled()
        @activeRepl.warnIsNotCompiled()
        return
      doIt()
    else
      @openPostWindow(@defaultURI)
        .then doIt

  openToSyntaxError: (path, line, char) ->
    @openFile(path, null, line, char)

{'fraction_non_alphanumeric': 0.1210419734904271, 'fraction_numerical': 0.0033136966126656848, 'mean_word_length': 2.2059604603127765, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1164560', 'n_tokens_mistral': 3317, 'n_tokens_neox': 3233, 'n_words': 735}