Move text insertion and auto indent/outdent code from the selection view to the model

This commit is contained in:
Nathan Sobo
2012-06-08 12:31:29 -06:00
parent f3144fe0d8
commit 7eb01272ed
8 changed files with 84 additions and 42 deletions

View File

@@ -307,7 +307,7 @@ describe "Selection", ->
describe "inserting text", ->
it "destroys the fold", ->
selection.setBufferRange([[1,0], [2,0]])
selection.insertText('holy cow')
editor.insertText('holy cow')
expect(editor.screenLineForRow(3).text).toBe buffer.lineForRow(3)
describe "backspace", ->

View File

@@ -2,7 +2,8 @@ Range = require 'range'
module.exports =
class AceOutdentAdaptor
constructor: (@buffer, @editor) ->
constructor: (@editSession) ->
@buffer = @editSession.buffer
getLine: (row) ->
@buffer.lineForRow(row)
@@ -13,9 +14,9 @@ class AceOutdentAdaptor
# Does not actually replace text, just line at range.start outdents one level
replace: (range, text) ->
{row, column} = @editor.getCursorBufferPosition()
{row, column} = @editSession.getCursorBufferPosition()
start = range.start
end = {row: range.start.row, column: range.start.column + @editor.tabText.length}
end = {row: range.start.row, column: range.start.column + @editSession.tabText.length}
@buffer.change(new Range(start, end), "")
@editor.setCursorBufferPosition({row, column: column - @editor.tabText.length})
@editSession.setCursorBufferPosition({row, column: column - @editSession.tabText.length})

View File

@@ -36,6 +36,9 @@ class Cursor
getBufferPosition: ->
@anchor.getBufferPosition()
getCurrentScreenRow: ->
@getScreenPosition().row
getCurrentBufferRow: ->
@getBufferPosition().row

View File

@@ -26,6 +26,7 @@ class EditSession
constructor: (@editor, @buffer) ->
@id = @constructor.idCounter++
@tabText = @editor.tabText
@renderer = new Renderer(@buffer, { softWrapColumn: @editor.calcSoftWrapColumn(), tabText: @editor.tabText })
@cursors = []
@selections = []
@@ -65,6 +66,9 @@ class EditSession
setScrollLeft: (@scrollLeft) ->
getScrollLeft: -> @scrollLeft
autoIndentEnabled: ->
@editor.autoIndent
screenPositionForBufferPosition: (bufferPosition, options) ->
@renderer.screenPositionForBufferPosition(bufferPosition, options)
@@ -92,8 +96,26 @@ class EditSession
backwardsScanInRange: (args...) ->
@buffer.backwardsScanInRange(args...)
getCursors: -> @cursors
getSelections: -> @selections
getCurrentMode: ->
@buffer.getMode()
insertText: (text) ->
@mutateSelectedText (selection) -> selection.insertText(text)
destroyFoldsContainingBufferRow: (bufferRow) ->
@renderer.destroyFoldsContainingBufferRow(bufferRow)
mutateSelectedText: (fn) ->
selections = @getSelections()
@buffer.startUndoBatch(@getSelectedBufferRanges())
fn(selection) for selection in selections
@buffer.endUndoBatch(@getSelectedBufferRanges())
stateForScreenRow: (screenRow) ->
@renderer.stateForScreenRow(screenRow)
getCursors: -> new Array(@cursors...)
getSelections: -> new Array(@selections...)
addCursorAtScreenPosition: (screenPosition) ->
@addCursor(new Cursor(editSession: this, screenPosition: screenPosition))
@@ -107,14 +129,17 @@ class EditSession
@addSelectionForCursor(cursor)
cursor
removeCursor: (cursor) ->
_.remove(@cursors, cursor)
addSelectionForCursor: (cursor) ->
selection = new Selection(editSession: this, cursor: cursor)
@selections.push(selection)
@trigger 'add-selection', selection
selection
removeCursor: (cursor) ->
_.remove(@cursors, cursor)
removeSelection: (selection) ->
_.remove(@selections, selection)
getLastCursor: ->
_.last(@cursors)
@@ -131,6 +156,9 @@ class EditSession
getCursorBufferPosition: ->
@getLastCursor().getBufferPosition()
getSelectedBufferRanges: ->
selection.getBufferRange() for selection in @selections
moveCursorUp: ->
@moveCursors (cursor) -> cursor.moveUp()

View File

@@ -707,7 +707,7 @@ class Editor extends View
backwardsScanInRange: (args...) -> @buffer.backwardsScanInRange(args...)
insertText: (text) ->
@compositeSelection.insertText(text)
@activeEditSession.insertText(text)
insertNewline: ->
@insertText('\n')
@@ -719,9 +719,9 @@ class Editor extends View
insertTab: ->
if @getSelection().isEmpty()
if @softTabs
@compositeSelection.insertText(@tabText)
@insertText(@tabText)
else
@compositeSelection.insertText('\t')
@insertText('\t')
else
@compositeSelection.indentSelectedRows()

View File

@@ -159,6 +159,9 @@ class Renderer
bufferPositionForScreenPosition: (position, options) ->
@lineMap.bufferPositionForScreenPosition(position, options)
stateForScreenRow: (screenRow) ->
@highlighter.stateForRow(screenRow)
clipScreenPosition: (position, options) ->
@lineMap.clipScreenPosition(position, options)

View File

@@ -97,16 +97,6 @@ class SelectionView extends View
intersectsBufferRange: (bufferRange) ->
@getBufferRange().intersectsWith(bufferRange)
insertText: (text) ->
{ text, shouldOutdent } = @autoIndentText(text)
oldBufferRange = @getBufferRange()
@editor.destroyFoldsContainingBufferRow(oldBufferRange.end.row)
wasReversed = @isReversed()
@clearSelection()
newBufferRange = @editor.buffer.change(oldBufferRange, text)
@cursor.setBufferPosition(newBufferRange.end, skipAtomicTokens: true) if wasReversed
@autoOutdentText() if shouldOutdent
indentSelectedRows: ->
range = @getBufferRange()
for row in [range.start.row..range.end.row]
@@ -124,26 +114,6 @@ class SelectionView extends View
@modifySelection =>
@editor.toggleLineCommentsInRange(@getBufferRange())
autoIndentText: (text) ->
if @editor.autoIndent
mode = @editor.getCurrentMode()
row = @cursor.getScreenPosition().row
state = @editor.stateForScreenRow(row)
lineBeforeCursor = @cursor.getCurrentBufferLine()[0...@cursor.getBufferPosition().column]
if text[0] == "\n"
indent = mode.getNextLineIndent(state, lineBeforeCursor, @editor.tabText)
text = text[0] + indent + text[1..]
else if mode.checkOutdent(state, lineBeforeCursor, text)
shouldOutdent = true
{text, shouldOutdent}
autoOutdentText: ->
screenRow = @cursor.getScreenPosition().row
bufferRow = @cursor.getBufferPosition().row
state = @editor.renderer.lineForRow(screenRow).state
@editor.getCurrentMode().autoOutdent(state, new AceOutdentAdaptor(@editor.buffer, @editor), bufferRow)
backspace: ->
@editor.destroyFoldsContainingBufferRow(@getBufferRange().end.row)
@selectLeft() if @isEmpty()

View File

@@ -1,6 +1,7 @@
Range = require 'range'
Anchor = require 'new-anchor'
EventEmitter = require 'event-emitter'
AceOutdentAdaptor = require 'ace-outdent-adaptor'
_ = require 'underscore'
module.exports =
@@ -11,6 +12,12 @@ class Selection
@cursor.on 'change-screen-position', (e) =>
@trigger 'change-screen-range', @getScreenRange() unless e.bufferChanged
@cursor.on 'destroy', => @destroy()
destroy: ->
@cursor.off()
@editSession.removeSelection(this)
getScreenRange: ->
if @anchor
new Range(@anchor.getScreenPosition(), @cursor.getScreenPosition())
@@ -43,6 +50,36 @@ class Selection
isReversed: ->
not @isEmpty() and @cursor.getBufferPosition().isLessThan(@anchor.getBufferPosition())
insertText: (text) ->
{ text, shouldOutdent } = @autoIndentText(text)
oldBufferRange = @getBufferRange()
@editSession.destroyFoldsContainingBufferRow(oldBufferRange.end.row)
wasReversed = @isReversed()
@clear()
newBufferRange = @editSession.buffer.change(oldBufferRange, text)
@cursor.setBufferPosition(newBufferRange.end, skipAtomicTokens: true) if wasReversed
@autoOutdentText() if shouldOutdent
autoIndentText: (text) ->
if @editSession.autoIndentEnabled()
mode = @editSession.getCurrentMode()
row = @cursor.getCurrentScreenRow()
state = @editSession.stateForScreenRow(row)
lineBeforeCursor = @cursor.getCurrentBufferLine()[0...@cursor.getBufferPosition().column]
if text[0] == "\n"
indent = mode.getNextLineIndent(state, lineBeforeCursor, @editSession.tabText)
text = text[0] + indent + text[1..]
else if mode.checkOutdent(state, lineBeforeCursor, text)
shouldOutdent = true
{text, shouldOutdent}
autoOutdentText: ->
screenRow = @cursor.getCurrentScreenRow()
bufferRow = @cursor.getCurrentBufferRow()
state = @editSession.stateForScreenRow(screenRow)
@editSession.getCurrentMode().autoOutdent(state, new AceOutdentAdaptor(@editSession), bufferRow)
handleBufferChange: (e) ->
@modifyScreenRange =>
@anchor?.handleBufferChange(e)