<commit_before>var Changeset = require('./Changeset');
var ChangesetUtils = require('./ChangesetUtils');
var _ = require('./underscore');

var AttributeManager = function(rep, applyChangesetCallback)
{
  this.rep = rep;
  this.applyChangesetCallback = applyChangesetCallback;
  this.author = '';
};

AttributeManager.prototype = _(AttributeManager.prototype).extend({
  
  applyChangeset: function(changeset){
    var cs = changeset.toString();
    if (!Changeset.isIdentity(cs))
    {
      this.applyChangesetCallback(cs);
    }
  },
  
  lineHasMarker: function(lineNum){
    // get "list" attribute of first char of line
    return this.getAttributeOnLine(lineNum, 'list');
  },
  
  getAttributeOnLine: function(lineNum, attributeName){
    // get  `attributeName` attribute of first char of line
    var aline = this.rep.alines[lineNum];
    if (aline)
    {
      var opIter = Changeset.opIterator(aline);
      if (opIter.hasNext())
      {
        return Changeset.opAttributeValue(opIter.next(), attributeName, this.rep.apool) || '';
      }
    }
    return '';
  },
  
  /*
    Sets a specified attribute on a line
    @param lineNum: the number of the line to set the attribute for
    @param attributeKey: the name of the attribute to set, e.g. list
    @param attributeValue: an optional parameter to pass to the attribute (e.g. indention level)
  
  */
  setAttributeOnLine: function(lineNum, attributeName, attributeValue){
    var loc = [0,0];
    var builder = Changeset.builder(this.rep.lines.totalWidth());
    var hasMarker = this.lineHasMarker(lineNum);
    
    ChangesetUtils.buildKeepRange(this.rep, builder, loc, (loc = [lineNum, 0]));

    if(hasMarker){
      ChangesetUtils.buildKeepRange(this.rep, builder, loc, (loc = [lineNum, 1]), [
        [attributeName, attributeValue]
      ], this.rep.apool);
    }else{      
        // add a line marker
        builder.insert('*', [
          ['author', this.author],
          ['insertorder', 'first'],
          [attributeName, attributeValue]
        ], this.rep.apool);
    }
    
    return this.applyChangeset(builder);
  },
  
  /*
     Removes a specified attribute on a line
     @param lineNum: the number of the affected line
     @param attributeKey: the name of the attribute to remove, e.g. list

   */
   removeAttributeOnLine: function(lineNum, attributeName, attributeValue){
     
     var loc = [0,0];
     var builder = Changeset.builder(this.rep.lines.totalWidth());
     var hasMarker = this.lineHasMarker(lineNum);
     
     // TODO
     
     if(hasMarker){
       ChangesetUtils.buildKeepRange(this.rep, builder, loc, (loc = [lineNum, 0]), [
         [attributeName, attributeValue]
       ], this.rep.apool);
       ChangesetUtils.buildRemoveRange(this.rep, builder, loc, (loc = [lineNum, 1]));
     }
     
     return this.applyChangeset(builder);
   },
  
   /*
     Sets a specified attribute on a line
     @param lineNum: the number of the line to set the attribute for
     @param attributeKey: the name of the attribute to set, e.g. list
     @param attributeValue: an optional parameter to pass to the attribute (e.g. indention level)
  */<commit_msg>Fixing bug where lists get deleted when pressing enter<commit_after>var Changeset = require('./Changeset');
var ChangesetUtils = require('./ChangesetUtils');
var _ = require('./underscore');

var AttributeManager = function(rep, applyChangesetCallback)
{
  this.rep = rep;
  this.applyChangesetCallback = applyChangesetCallback;
  this.author = '';
};

AttributeManager.prototype = _(AttributeManager.prototype).extend({
  
  applyChangeset: function(changeset){
    var cs = changeset.toString();
    if (!Changeset.isIdentity(cs))
    {
      this.applyChangesetCallback(cs);
    }
  },
  
  lineHasMarker: function(lineNum){
    // get "list" attribute of first char of line
    return this.getAttributeOnLine(lineNum, 'list');
  },
  
  getAttributeOnLine: function(lineNum, attributeName){
    // get  `attributeName` attribute of first char of line
    var aline = this.rep.alines[lineNum];
    if (aline)
    {
      var opIter = Changeset.opIterator(aline);
      if (opIter.hasNext())
      {
        return Changeset.opAttributeValue(opIter.next(), attributeName, this.rep.apool) || '';
      }
    }
    return '';
  },
  
  /*
    Sets a specified attribute on a line
    @param lineNum: the number of the line to set the attribute for
    @param attributeKey: the name of the attribute to set, e.g. list
    @param attributeValue: an optional parameter to pass to the attribute (e.g. indention level)
  
  */
  setAttributeOnLine: function(lineNum, attributeName, attributeValue){
    var loc = [0,0];
    var builder = Changeset.builder(this.rep.lines.totalWidth());
    var hasMarker = this.lineHasMarker(lineNum);
    
    ChangesetUtils.buildKeepRange(this.rep, builder, loc, (loc = [lineNum, 0]));

    if(hasMarker){
      ChangesetUtils.buildKeepRange(this.rep, builder, loc, (loc = [lineNum, 1]), [
        [attributeName, attributeValue]
      ], this.rep.apool);
    }else{      
        // add a line marker
        builder.insert('*', [
          ['author', this.author],
          ['insertorder', 'first'],
          [attributeName, attributeValue]
        ], this.rep.apool);
    }
    
    return this.applyChangeset(builder);
  },
  
  /*
     Removes a specified attribute on a line
     @param lineNum: the number of the affected line
     @param attributeKey: the name of the attribute to remove, e.g. list

   */
   removeAttributeOnLine: function(lineNum, attributeName, attributeValue){
     
     var loc = [0,0];
     var builder = Changeset.builder(this.rep.lines.totalWidth());
     var hasMarker = this.lineHasMarker(lineNum);
     
     // TODO
     
     if(hasMarker){
       ChangesetUtils.buildKeepRange(this.rep, builder, loc, (loc = [lineNum, 0]));
       ChangesetUtils.buildRemoveRange(this.rep, builder, loc, (loc = [lineNum, 1]));
     }
     
     return this.applyChangeset(builder);
   },
  
   /*
     Sets a specified attribute on a line
     @param lineNum: the number of the line to set the attribute for
     @param attributeKey: the name of the attribute to set, e.g. list
     @param attributeValue: an optional parameter to pass to the attribute (e.g. indention level)
  */
{'fraction_non_alphanumeric': 0.11670371546522705, 'fraction_numerical': 0.0025404890441409972, 'mean_word_length': 2.9616352201257863, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '2116762', 'n_tokens_mistral': 1864, 'n_tokens_neox': 1847, 'n_words': 513}