aboutsummaryrefslogtreecommitdiff
path: root/atom/packages/vim-mode/lib/motions/find-motion.coffee
blob: 2a577a8b03ff74672ffa3b93260ad733d36fff8d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
{MotionWithInput} = require './general-motions'
{ViewModel} = require '../view-models/view-model'
{Point, Range} = require 'atom'

class Find extends MotionWithInput
  operatesInclusively: true

  constructor: (@editor, @vimState, opts={}) ->
    super(@editor, @vimState)
    @offset = 0

    if not opts.repeated
      @viewModel = new ViewModel(this, class: 'find', singleChar: true, hidden: true)
      @backwards = false
      @repeated = false
      @vimState.globalVimState.currentFind = this

    else
      @repeated = true

      orig = @vimState.globalVimState.currentFind
      @backwards = orig.backwards
      @complete = orig.complete
      @input = orig.input

      @reverse() if opts.reverse

  match: (cursor, count) ->
    currentPosition = cursor.getBufferPosition()
    line = @editor.lineTextForBufferRow(currentPosition.row)
    if @backwards
      index = currentPosition.column
      for i in [0..count-1]
        return if index <= 0 # we can't move backwards any further, quick return
        index = line.lastIndexOf(@input.characters, index-1-(@offset*@repeated))
      if index >= 0
        new Point(currentPosition.row, index + @offset)
    else
      index = currentPosition.column
      for i in [0..count-1]
        index = line.indexOf(@input.characters, index+1+(@offset*@repeated))
        return if index < 0 # no match found
      if index >= 0
        new Point(currentPosition.row, index - @offset)

  reverse: ->
    @backwards = not @backwards
    this

  moveCursor: (cursor, count=1) ->
    if (match = @match(cursor, count))?
      cursor.setBufferPosition(match)

class Till extends Find
  constructor: (@editor, @vimState, opts={}) ->
    super(@editor, @vimState, opts)
    @offset = 1

  match: ->
    @selectAtLeastOne = false
    retval = super
    if retval? and not @backwards
      @selectAtLeastOne = true
    retval

  moveSelectionInclusively: (selection, count, options) ->
    super
    if selection.isEmpty() and @selectAtLeastOne
      selection.modifySelection ->
        selection.cursor.moveRight()

module.exports = {Find, Till}