   # Returns nothing.
   execute: (count=1) ->
     cursor = @editor.getCursor()
-    buffer = @editor.getBuffer()
-
-    buffer.transact =>
+
+    @undoTransaction =>
       _.times count, =>
         if _.last(@motion.select(1, @selectOptions))
           @editor.getSelection().delete()

  #
  # Returns nothing.
  execute: (count=1) ->
    buffer = @editor.getBuffer()

    buffer.transact =>
      _.times count, =>
        @editor.joinLine()

  # Public: Not implemented.
  #
  # Returns nothing.
  compose: (register) ->
    throw new OperatorError("Not Implemented")

module.exports = { OperatorError, Delete, Yank, Put, Join, Indent, Outdent, Change }

  constructor: (@message) ->
    @name = "Operator Error"

class Operator
  vimState: null
  motion: null
  complete: null
  selectOptions: null

  # selectOptions - The options object to pass through to the motion when
  #                 selecting.
  constructor: (@editor, @vimState, {@selectOptions}={}) ->
    @complete = false

  # Public: Determines when the command can be executed.
  #
  # Returns true if ready to execute and false otherwise.
  isComplete: -> @complete

  # Public: Marks this as ready to execute and saves the motion.
  #
  # motion - The motion used to select what to operate on.
  #
  # Returns nothing.
  compose: (motion) ->
    if not motion.select
      throw new OperatorError("Must compose with a motion")

    @motion = motion
    @complete = true


  # Protected: Wraps the function within an single undo step.
  #
  # fn - The function to wrap.
  #
  # Returns nothing.
  undoTransaction: (fn) ->
    @editor.getBuffer().transact(fn)
#
# It deletes everything selected by the following motion.
#
class Delete extends Operator
  allowEOL: null

  # allowEOL - Determines whether the cursor should be allowed to rest on the
  #            end of line character or not.
  constructor: (@editor, @vimState, {@allowEOL, @selectOptions}={}) ->
    @complete = false

  # Public: Deletes the text selected by the given motion.
  #
  # count - The number of times to execute.
