<commit_before>View = require 'views/kinds/CocoView'
template = require 'templates/play/level/tome/spell'
{me} = require 'lib/auth'
filters = require 'lib/image_filter'
Range = ace.require("ace/range").Range
Problem = require './problem'
SpellDebugView = require './spell_debug_view'
SpellToolbarView = require './spell_toolbar_view'
LevelComponent = require 'models/LevelComponent'

module.exports = class SpellView extends View
  id: 'spell-view'
  className: 'shown'
  template: template
  controlsEnabled: true
  eventsSuppressed: true
  writable: true

  editModes:
    'javascript': 'ace/mode/javascript'
    'coffeescript': 'ace/mode/coffee'
    'python': 'ace/mode/python'
    'clojure': 'ace/mode/clojure'
    'lua': 'ace/mode/lua'
    'io': 'ace/mode/text'

  keyBindings:
    'default': null
    'vim': 'ace/keyboard/vim'
    'emacs': 'ace/keyboard/emacs'

  subscriptions:
    'level-disable-controls': 'onDisableControls'
    'level-enable-controls': 'onEnableControls'
    'surface:frame-changed': 'onFrameChanged'
    'surface:coordinate-selected': 'onCoordinateSelected'
    'god:new-world-created': 'onNewWorld'
    'god:user-code-problem': 'onUserCodeProblem'
    'god:non-user-code-problem': 'onNonUserCodeProblem'
    'tome:manual-cast': 'onManualCast'
    'tome:reload-code': 'onCodeReload'
    'tome:spell-changed': 'onSpellChanged'
    'level:session-will-save': 'onSessionWillSave'
    'modal-closed': 'focus'
    'focus-editor': 'focus'
    'tome:spell-statement-index-updated': 'onStatementIndexUpdated'
    'tome:change-language': 'onChangeLanguage'
    'tome:change-config': 'onChangeEditorConfig'
    'tome:update-snippets': 'addZatannaSnippets'
    'spell-beautify': 'onSpellBeautify'

  events:
    'mouseout': 'onMouseOut'

  constructor: (options) ->
    super options
    @worker = options.worker
    @session = options.session
    @listenTo(@session, 'change:multiplayer', @onMultiplayerChanged)
    @spell = options.spell
    @problems = []
    @writable = false unless me.team in @spell.permissions.readwrite  # TODO: make this do anything
    @highlightCurrentLine = _.throttle @highlightCurrentLine, 100

  afterRender: ->
    super()
    @createACE()
    @createACEShortcuts()
    @fillACE()
    if @session.get('multiplayer')
      @createFirepad()
    else
      # needs to happen after the code generating this view is complete
      _.defer @onAllLoaded

  createACE: ->
    # Test themes and settings here: http://ace.ajax.org/build/kitchen-sink.html
    aceConfig = me.get('aceConfig') ? {}
    @ace = ace.edit @$el.find('.ace')[0]
    @aceSession = @ace.getSession()
    @aceDoc = @aceSession.getDocument()
    @aceSession.setUseWorker false
    @aceSession.setMode @editModes[@spell.language]
    @aceSession.setWrapLimitRange null
    @aceSession.setUseWrapMode true
    @aceSession.setNewLineMode "unix"
    @aceSession.setUseSoftTabs true
    @ace.setTheme 'ace/theme/textmate'
    @ace.setDisplayIndentGuides aceConfig.indentGuides
    @ace.setShowPrintMargin false
    @ace.setShowInvisibles aceConfig.invisibles
    @ace.setBehavioursEnabled aceConfig.behaviors
    @ace.setAnimatedScroll true
    @ace.setKeyboardHandler @keyBindings[aceConfig.keyBindings ? 'default']
    @toggleControls null, @writable
    @aceSession.selection.on 'changeCursor', @onCursorActivity
    $(@ace.container).find('.ace_gutter').on 'click', '.ace_error, .ace_warning, .ace_info', @onAnnotationClick
    @zatanna = new Zatanna @ace,
      liveCompletion: aceConfig.liveCompletion ? true
      completers:
        keywords: false

  createACEShortcuts: ->
    @aceCommands = aceCommands = []
    ace = @ace
    addCommand = (c) ->
      ace.commands.addCommand c
      aceCommands.push c.name
    addCommand
      name: 'run-code'
      bindKey: {win: 'Shift-Enter|Ctrl-Enter', mac: 'Shift-Enter|Command-Enter|Ctrl-Enter'}
      exec: -> Backbone.Mediator.publish 'tome:manual-cast', {}
    addCommand
      name: 'no-op'
      bindKey: {win: 'Ctrl-S', mac: 'Command-S|Ctrl-S'}
      exec: ->  # just prevent page save call
    addCommand
      name: 'toggle-playing'
      bindKey: {win: 'Ctrl-P', mac: 'Command-P|Ctrl-P'}
      exec: -> Backbone.Mediator.publish 'level-toggle-playing'
    addCommand
      name: 'end-current-script'
      bindKey: {win: 'Shift-Space', mac: 'Shift-Space'}
      passEvent: true  # https://github.com/ajaxorg/ace/blob/master/lib/ace/keyboard/keybinding.js#L114
    # No easy way to selectively cancel shift+space, since we don't get access to the event.
    # Maybe we could temporarily set ourselves to read-only if we somehow know that a script is active?
      exec: -> Backbone.Mediator.publish 'level:shift-space-pressed'
    addCommand
      name: 'end-all-scripts'
      bindKey: {win: 'Escape', mac: 'Escape'}
      exec: -> Backbone.Mediator.publish 'level:escape-pressed'
    addCommand
      name: 'toggle-grid'
      bindKey: {win: 'Ctrl-G', mac: 'Command-G|Ctrl-G'}
      exec: -> Backbone.Mediator.publish 'level-toggle-grid'
    addCommand
      name: 'toggle-debug'
      bindKey: {win: 'Ctrl-\\', mac: 'Command-\\|Ctrl-\\'}
      exec: -> Backbone.Mediator.publish 'level-toggle-debug'
    addCommand
      name: 'toggle-pathfinding'
      bindKey: {win: 'Ctrl-O', mac: 'Command-O|Ctrl-O'}
      exec: -> Backbone.Mediator.publish 'level-toggle-pathfinding'
    addCommand
      name: 'level-scrub-forward'
      bindKey: {win: 'Ctrl-]', mac: 'Command-]|Ctrl-]'}
      exec: -> Backbone.Mediator.publish 'level-scrub-forward'
    addCommand
      name: 'level-scrub-back'
      bindKey: {win: 'Ctrl-[', mac: 'Command-[|Ctrl-]'}
      exec: -> Backbone.Mediator.publish 'level-scrub-back'
    addCommand
      name: 'spell-step-forward'
      bindKey: {win: 'Ctrl-Alt-]', mac: 'Command-Alt-]|Ctrl-Alt-]'}
      exec: -> Backbone.Mediator.publish 'spell-step-forward'
    addCommand
      name: 'spell-step-backward'
      bindKey: {win: 'Ctrl-Alt-[', mac: 'Command-Alt-[|Ctrl-Alt-]'}
      exec: -> Backbone.Mediator.publish 'spell-step-backward'
    addCommand
      name: 'spell-beautify'
      bindKey: {win: 'Ctrl-Shift-B', mac: 'Command-Shift-B|Ctrl-Shift-B'}
      exec: -> Backbone.Mediator.publish 'spell-beautify'
    addCommand
      name: 'prevent-line-jump'
      bindKey: {win: 'Ctrl-L', mac: 'Command-L'}
      passEvent: true
      exec: ->  # just prevent default ACE go-to-line alert

  fillACE: ->
    @ace.setValue @spell.source
    @ace.clearSelection()

  addZatannaSnippets: (e) ->
    snippetEntries = []
    for owner, props of e.propGroups
      for prop in props
        doc = _.find (e.allDocs['__' + prop] ? []), (doc) ->
          return true if doc.owner is owner
          return (owner is 'this' or owner is 'more') and (not doc.owner? or doc.owner is 'this')
        console.log 'could not find doc for', prop, 'from', e.allDocs['__' + prop], 'for', owner, 'of', propGroups unless doc
        doc ?= prop
        if doc.snippets?
          entry = 
            content: doc.snippets[@spell.language].code
            name: doc.name
            tabTrigger: doc.snippets[@spell.language].tab
          snippetEntries.push entry

    window.zatanna = @zatanna
    window.snippetEntries = snippetEntries
    @zatanna.addSnippets snippetEntries, @spell.language

  onMultiplayerChanged: ->
    if @session.get('multiplayer')
      @createFirepad()
    else
      @firepad?.dispose()
<commit_msg>Fixed a bug with logging missing documentation.<commit_after>View = require 'views/kinds/CocoView'
template = require 'templates/play/level/tome/spell'
{me} = require 'lib/auth'
filters = require 'lib/image_filter'
Range = ace.require("ace/range").Range
Problem = require './problem'
SpellDebugView = require './spell_debug_view'
SpellToolbarView = require './spell_toolbar_view'
LevelComponent = require 'models/LevelComponent'

module.exports = class SpellView extends View
  id: 'spell-view'
  className: 'shown'
  template: template
  controlsEnabled: true
  eventsSuppressed: true
  writable: true

  editModes:
    'javascript': 'ace/mode/javascript'
    'coffeescript': 'ace/mode/coffee'
    'python': 'ace/mode/python'
    'clojure': 'ace/mode/clojure'
    'lua': 'ace/mode/lua'
    'io': 'ace/mode/text'

  keyBindings:
    'default': null
    'vim': 'ace/keyboard/vim'
    'emacs': 'ace/keyboard/emacs'

  subscriptions:
    'level-disable-controls': 'onDisableControls'
    'level-enable-controls': 'onEnableControls'
    'surface:frame-changed': 'onFrameChanged'
    'surface:coordinate-selected': 'onCoordinateSelected'
    'god:new-world-created': 'onNewWorld'
    'god:user-code-problem': 'onUserCodeProblem'
    'god:non-user-code-problem': 'onNonUserCodeProblem'
    'tome:manual-cast': 'onManualCast'
    'tome:reload-code': 'onCodeReload'
    'tome:spell-changed': 'onSpellChanged'
    'level:session-will-save': 'onSessionWillSave'
    'modal-closed': 'focus'
    'focus-editor': 'focus'
    'tome:spell-statement-index-updated': 'onStatementIndexUpdated'
    'tome:change-language': 'onChangeLanguage'
    'tome:change-config': 'onChangeEditorConfig'
    'tome:update-snippets': 'addZatannaSnippets'
    'spell-beautify': 'onSpellBeautify'

  events:
    'mouseout': 'onMouseOut'

  constructor: (options) ->
    super options
    @worker = options.worker
    @session = options.session
    @listenTo(@session, 'change:multiplayer', @onMultiplayerChanged)
    @spell = options.spell
    @problems = []
    @writable = false unless me.team in @spell.permissions.readwrite  # TODO: make this do anything
    @highlightCurrentLine = _.throttle @highlightCurrentLine, 100

  afterRender: ->
    super()
    @createACE()
    @createACEShortcuts()
    @fillACE()
    if @session.get('multiplayer')
      @createFirepad()
    else
      # needs to happen after the code generating this view is complete
      _.defer @onAllLoaded

  createACE: ->
    # Test themes and settings here: http://ace.ajax.org/build/kitchen-sink.html
    aceConfig = me.get('aceConfig') ? {}
    @ace = ace.edit @$el.find('.ace')[0]
    @aceSession = @ace.getSession()
    @aceDoc = @aceSession.getDocument()
    @aceSession.setUseWorker false
    @aceSession.setMode @editModes[@spell.language]
    @aceSession.setWrapLimitRange null
    @aceSession.setUseWrapMode true
    @aceSession.setNewLineMode "unix"
    @aceSession.setUseSoftTabs true
    @ace.setTheme 'ace/theme/textmate'
    @ace.setDisplayIndentGuides aceConfig.indentGuides
    @ace.setShowPrintMargin false
    @ace.setShowInvisibles aceConfig.invisibles
    @ace.setBehavioursEnabled aceConfig.behaviors
    @ace.setAnimatedScroll true
    @ace.setKeyboardHandler @keyBindings[aceConfig.keyBindings ? 'default']
    @toggleControls null, @writable
    @aceSession.selection.on 'changeCursor', @onCursorActivity
    $(@ace.container).find('.ace_gutter').on 'click', '.ace_error, .ace_warning, .ace_info', @onAnnotationClick
    @zatanna = new Zatanna @ace,
      liveCompletion: aceConfig.liveCompletion ? true
      completers:
        keywords: false

  createACEShortcuts: ->
    @aceCommands = aceCommands = []
    ace = @ace
    addCommand = (c) ->
      ace.commands.addCommand c
      aceCommands.push c.name
    addCommand
      name: 'run-code'
      bindKey: {win: 'Shift-Enter|Ctrl-Enter', mac: 'Shift-Enter|Command-Enter|Ctrl-Enter'}
      exec: -> Backbone.Mediator.publish 'tome:manual-cast', {}
    addCommand
      name: 'no-op'
      bindKey: {win: 'Ctrl-S', mac: 'Command-S|Ctrl-S'}
      exec: ->  # just prevent page save call
    addCommand
      name: 'toggle-playing'
      bindKey: {win: 'Ctrl-P', mac: 'Command-P|Ctrl-P'}
      exec: -> Backbone.Mediator.publish 'level-toggle-playing'
    addCommand
      name: 'end-current-script'
      bindKey: {win: 'Shift-Space', mac: 'Shift-Space'}
      passEvent: true  # https://github.com/ajaxorg/ace/blob/master/lib/ace/keyboard/keybinding.js#L114
    # No easy way to selectively cancel shift+space, since we don't get access to the event.
    # Maybe we could temporarily set ourselves to read-only if we somehow know that a script is active?
      exec: -> Backbone.Mediator.publish 'level:shift-space-pressed'
    addCommand
      name: 'end-all-scripts'
      bindKey: {win: 'Escape', mac: 'Escape'}
      exec: -> Backbone.Mediator.publish 'level:escape-pressed'
    addCommand
      name: 'toggle-grid'
      bindKey: {win: 'Ctrl-G', mac: 'Command-G|Ctrl-G'}
      exec: -> Backbone.Mediator.publish 'level-toggle-grid'
    addCommand
      name: 'toggle-debug'
      bindKey: {win: 'Ctrl-\\', mac: 'Command-\\|Ctrl-\\'}
      exec: -> Backbone.Mediator.publish 'level-toggle-debug'
    addCommand
      name: 'toggle-pathfinding'
      bindKey: {win: 'Ctrl-O', mac: 'Command-O|Ctrl-O'}
      exec: -> Backbone.Mediator.publish 'level-toggle-pathfinding'
    addCommand
      name: 'level-scrub-forward'
      bindKey: {win: 'Ctrl-]', mac: 'Command-]|Ctrl-]'}
      exec: -> Backbone.Mediator.publish 'level-scrub-forward'
    addCommand
      name: 'level-scrub-back'
      bindKey: {win: 'Ctrl-[', mac: 'Command-[|Ctrl-]'}
      exec: -> Backbone.Mediator.publish 'level-scrub-back'
    addCommand
      name: 'spell-step-forward'
      bindKey: {win: 'Ctrl-Alt-]', mac: 'Command-Alt-]|Ctrl-Alt-]'}
      exec: -> Backbone.Mediator.publish 'spell-step-forward'
    addCommand
      name: 'spell-step-backward'
      bindKey: {win: 'Ctrl-Alt-[', mac: 'Command-Alt-[|Ctrl-Alt-]'}
      exec: -> Backbone.Mediator.publish 'spell-step-backward'
    addCommand
      name: 'spell-beautify'
      bindKey: {win: 'Ctrl-Shift-B', mac: 'Command-Shift-B|Ctrl-Shift-B'}
      exec: -> Backbone.Mediator.publish 'spell-beautify'
    addCommand
      name: 'prevent-line-jump'
      bindKey: {win: 'Ctrl-L', mac: 'Command-L'}
      passEvent: true
      exec: ->  # just prevent default ACE go-to-line alert

  fillACE: ->
    @ace.setValue @spell.source
    @ace.clearSelection()

  addZatannaSnippets: (e) ->
    snippetEntries = []
    for owner, props of e.propGroups
      for prop in props
        doc = _.find (e.allDocs['__' + prop] ? []), (doc) ->
          return true if doc.owner is owner
          return (owner is 'this' or owner is 'more') and (not doc.owner? or doc.owner is 'this')
        console.log 'could not find doc for', prop, 'from', e.allDocs['__' + prop], 'for', owner, 'of', e.propGroups unless doc
        doc ?= prop
        if doc.snippets?
          entry = 
            content: doc.snippets[@spell.language].code
            name: doc.name
            tabTrigger: doc.snippets[@spell.language].tab
          snippetEntries.push entry

    window.zatanna = @zatanna
    window.snippetEntries = snippetEntries
    @zatanna.addSnippets snippetEntries, @spell.language

  onMultiplayerChanged: ->
    if @session.get('multiplayer')
      @createFirepad()
    else
      @firepad?.dispose()

{'fraction_non_alphanumeric': 0.14004847831941827, 'fraction_numerical': 0.0009426339886883921, 'mean_word_length': 3.2304186841355738, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 49, 'https://': 2, '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': '6949512', 'n_tokens_mistral': 4959, 'n_tokens_neox': 4876, 'n_words': 1030}