<commit_before>grammarMap = require './grammars'
{View, BufferedProcess, $$} = require 'atom'
CodeContext = require './code-context'
HeaderView = require './header-view'
ScriptOptionsView = require './script-options-view'
AnsiFilter = require 'ansi-to-html'
_ = require 'underscore'

# Runs a portion of a script through an interpreter and displays it line by line
module.exports =
class ScriptView extends View
  @bufferedProcess: null

  @content: ->
    @div =>
      @subview 'headerView', new HeaderView()

      # Display layout and outlets
      css = 'tool-panel panel panel-bottom padding script-view
        native-key-bindings'
      @div class: css, outlet: 'script', tabindex: -1, =>
        @div class: 'panel-body padded output', outlet: 'output'

  initialize: (serializeState, @runOptions) ->
    # Bind commands
    atom.workspaceView.command 'script:run', => @start()
    atom.workspaceView.command 'script:run-at-line', => @start(true)
    atom.workspaceView.command 'script:close-view', => @close()
    atom.workspaceView.command 'script:kill-process', => @stop()

    @ansiFilter = new AnsiFilter

  serialize: ->

  updateOptions: (event) -> @runOptions = event.runOptions

  start: (lineBased = false) ->
    # Get current editor
    editor = atom.workspace.getActiveEditor()

    # No editor available, do nothing
    return unless editor?

    @resetView()
    commandContext = @setup editor, lineBased
    @run commandContext.command, commandContext.args if commandContext

  resetView: (title = 'Loading...') ->
    # Display window and load message

    # First run, create view
    atom.workspaceView.prependToBottom this unless @hasParent()

    # Close any existing process and start a new one
    @stop()

    @headerView.title.text title
    @headerView.setStatus 'start'

    # Get script view ready
    @output.empty()

  close: ->
    # Stop any running process and dismiss window
    @stop()
    @detach() if @hasParent()

  getLang: (editor) -> editor.getGrammar().name

  setup: (editor, lineBased = false) ->
    # Store information about the run, including language
    commandContext = {}

    # Get language
    lang = @getLang editor
    err = null

    # Determine if no language is selected.
    if lang is 'Null Grammar' or lang is 'Plain Text'
      err = $$ ->
        @p 'You must select a language in the lower left, or save the file
          with an appropriate extension.'

    # Provide them a dialog to submit an issue on GH, prepopulated with their
    # language of choice.
    else if not (lang of grammarMap)
      err = $$ ->
        @p class: 'block', "Command not configured for #{lang}!"
        @p class: 'block', =>
          @text 'Add an '
          @a href: "https://github.com/rgbkrk/atom-script/issues/\
            new?title=Add%20support%20for%20#{lang}", 'issue on GitHub'
          @text ' or send your own Pull Request.'

    if err?
      @handleError(err)
      return false

    filename = editor.getTitle()
    filepath = editor.getPath()
    selection = editor.getSelection()

    # If the selection was empty "select" ALL the text
    # This allows us to run on new files
    if selection.isEmpty()
      textSource = editor
    else
      textSource = selection

    codeContext = new CodeContext(filename, filepath, textSource)

    # No selected text on a file that does exist, use filepath
    if selection.isEmpty() and filepath? and not lineBased
      argType = 'File Based'
      editor.save()
    else if lineBased
      cursor = editor.getCursor()
      codeContext.lineNumber = cursor.getScreenRow() + 1
      argType = 'Line Based'
      editor.save()
    else
      argType = 'Selection Based'

    console.log "#{argType} executing"

    try
      if not @runOptions.cmd? or @runOptions.cmd is ''
        # Precondition: lang? and lang of grammarMap
        commandContext.command = grammarMap[lang][argType].command
      else
        commandContext.command = @runOptions.cmd

      buildArgsArray = grammarMap[lang][argType].args
      commandContext.args = buildArgsArray codeContext

    catch error
      err = $$ ->
        @p class: 'block', "#{argType} runner not available for #{lang}."
        @p class: 'block', =>
          @text 'If it should exist, add an '
          @a href: "https://github.com/rgbkrk/atom-script/issues/\
            new?title=Add%20support%20for%20#{lang}", 'issue on GitHub'
          @text ', or send your own pull request.'

      @handleError err
      return false

    # Update header to show the file name (and line number if applicable)
    @headerView.title.text codeContext.fileColonLine(false)

    # Return setup information
    return commandContext

  handleError: (err) ->
    # Display error and kill process
    @headerView.title.text 'Error'
    @headerView.setStatus 'err'
    @output.append err
    @stop()

  run: (command, extraArgs) ->
    atom.emit 'achievement:unlock', msg: 'Homestar Runner'

    # Default to where the user opened atom
    options =
      cwd: @getCwd()
      env: process.env
    args = (@runOptions.cmdArgs.concat extraArgs).concat @runOptions.scriptArgs

    stdout = (output) => @display 'stdout', output
    stderr = (output) => @display 'stderr', output
    exit = (returnCode) =>
      if returnCode is 0
        @headerView.setStatus 'stop'
      else
        @headerView.setStatus 'err'<commit_msg>Update header-view title for line based runs<commit_after>grammarMap = require './grammars'
{View, BufferedProcess, $$} = require 'atom'
CodeContext = require './code-context'
HeaderView = require './header-view'
ScriptOptionsView = require './script-options-view'
AnsiFilter = require 'ansi-to-html'
_ = require 'underscore'

# Runs a portion of a script through an interpreter and displays it line by line
module.exports =
class ScriptView extends View
  @bufferedProcess: null

  @content: ->
    @div =>
      @subview 'headerView', new HeaderView()

      # Display layout and outlets
      css = 'tool-panel panel panel-bottom padding script-view
        native-key-bindings'
      @div class: css, outlet: 'script', tabindex: -1, =>
        @div class: 'panel-body padded output', outlet: 'output'

  initialize: (serializeState, @runOptions) ->
    # Bind commands
    atom.workspaceView.command 'script:run', => @start()
    atom.workspaceView.command 'script:run-at-line', => @start(true)
    atom.workspaceView.command 'script:close-view', => @close()
    atom.workspaceView.command 'script:kill-process', => @stop()

    @ansiFilter = new AnsiFilter

  serialize: ->

  updateOptions: (event) -> @runOptions = event.runOptions

  start: (lineBased = false) ->
    # Get current editor
    editor = atom.workspace.getActiveEditor()

    # No editor available, do nothing
    return unless editor?

    @resetView()
    commandContext = @setup editor, lineBased
    @run commandContext.command, commandContext.args if commandContext

  resetView: (title = 'Loading...') ->
    # Display window and load message

    # First run, create view
    atom.workspaceView.prependToBottom this unless @hasParent()

    # Close any existing process and start a new one
    @stop()

    @headerView.title.text title
    @headerView.setStatus 'start'

    # Get script view ready
    @output.empty()

  close: ->
    # Stop any running process and dismiss window
    @stop()
    @detach() if @hasParent()

  getLang: (editor) -> editor.getGrammar().name

  setup: (editor, lineBased = false) ->
    # Store information about the run, including language
    commandContext = {}

    # Get language
    lang = @getLang editor
    err = null

    # Determine if no language is selected.
    if lang is 'Null Grammar' or lang is 'Plain Text'
      err = $$ ->
        @p 'You must select a language in the lower left, or save the file
          with an appropriate extension.'

    # Provide them a dialog to submit an issue on GH, prepopulated with their
    # language of choice.
    else if not (lang of grammarMap)
      err = $$ ->
        @p class: 'block', "Command not configured for #{lang}!"
        @p class: 'block', =>
          @text 'Add an '
          @a href: "https://github.com/rgbkrk/atom-script/issues/\
            new?title=Add%20support%20for%20#{lang}", 'issue on GitHub'
          @text ' or send your own Pull Request.'

    if err?
      @handleError(err)
      return false

    filename = editor.getTitle()
    filepath = editor.getPath()
    selection = editor.getSelection()

    # If the selection was empty "select" ALL the text
    # This allows us to run on new files
    if selection.isEmpty()
      textSource = editor
    else
      textSource = selection

    codeContext = new CodeContext(filename, filepath, textSource)

    # No selected text on a file that does exist, use filepath
    if selection.isEmpty() and filepath? and not lineBased
      argType = 'File Based'
      editor.save()
    else if lineBased
      cursor = editor.getCursor()
      codeContext.lineNumber = cursor.getScreenRow() + 1
      argType = 'Line Based'
      editor.save()
    else
      argType = 'Selection Based'

    console.log "#{argType} executing"

    try
      if not @runOptions.cmd? or @runOptions.cmd is ''
        # Precondition: lang? and lang of grammarMap
        commandContext.command = grammarMap[lang][argType].command
      else
        commandContext.command = @runOptions.cmd

      buildArgsArray = grammarMap[lang][argType].args
      commandContext.args = buildArgsArray codeContext

    catch error
      err = $$ ->
        @p class: 'block', "#{argType} runner not available for #{lang}."
        @p class: 'block', =>
          @text 'If it should exist, add an '
          @a href: "https://github.com/rgbkrk/atom-script/issues/\
            new?title=Add%20support%20for%20#{lang}", 'issue on GitHub'
          @text ', or send your own pull request.'

      @handleError err
      return false

    # Update header to show the lang and file name
    if argType is 'Line Based'
      @headerView.title.text "#{lang} - #{codeContext.fileColonLine(false)}"
    else
      @headerView.title.text "#{lang} - #{filename}"

    # Return setup information
    return commandContext

  handleError: (err) ->
    # Display error and kill process
    @headerView.title.text 'Error'
    @headerView.setStatus 'err'
    @output.append err
    @stop()

  run: (command, extraArgs) ->
    atom.emit 'achievement:unlock', msg: 'Homestar Runner'

    # Default to where the user opened atom
    options =
      cwd: @getCwd()
      env: process.env
    args = (@runOptions.cmdArgs.concat extraArgs).concat @runOptions.scriptArgs

    stdout = (output) => @display 'stdout', output
    stderr = (output) => @display 'stderr', output
    exit = (returnCode) =>
      if returnCode is 0
        @headerView.setStatus 'stop'
      else
        @headerView.setStatus 'err'
{'fraction_non_alphanumeric': 0.10951855935317897, 'fraction_numerical': 0.0027563395810363835, 'mean_word_length': 2.7940048797490413, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 53, 'https://': 4, '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': '6777517', 'n_tokens_mistral': 3199, 'n_tokens_neox': 3080, 'n_words': 1016}