Implement :s

This commit is contained in:
jazzpi 2015-03-22 23:14:56 +01:00
parent 161c55c94f
commit f662a96afd
4 changed files with 78 additions and 6 deletions

5
lib/command-error.coffee Normal file
View file

@ -0,0 +1,5 @@
class CommandError
constructor: (@message) ->
@name = 'Command Error'
module.exports = CommandError

View file

@ -1,10 +1,7 @@
ExViewModel = require './ex-view-model'
Ex = require './ex'
Find = require './find'
class CommandError
constructor: (@message) ->
@name = 'Command Error'
CommandError = require './command-error'
class Command
constructor: (@editor, @exState) ->
@ -164,4 +161,4 @@ class Command
else
throw new CommandError("Not an editor command: #{input.characters}")
module.exports = {Command, CommandError}
module.exports = Command

View file

@ -1,6 +1,7 @@
{Emitter, Disposable, CompositeDisposable} = require 'event-kit'
{Command, CommandError} = require './command'
Command = require './command'
CommandError = require './command-error'
class ExState
constructor: (@editorElement, @globalExState) ->

View file

@ -1,4 +1,5 @@
path = require 'path'
CommandError = require './command-error'
trySave = (func) ->
deferred = Promise.defer()
@ -33,6 +34,23 @@ getFullPath = (filePath) ->
return filePath if path.isAbsolute(filePath)
return path.join(atom.project.getPath(), filePath)
replaceGroups = (groups, replString) ->
arr = replString.split('')
offset = 0
cdiff = 0
while (m = replString.match(/(?:[^\\]|^)\\(\d)/))?
group = groups[m[1]] or ''
i = replString.indexOf(m[0])
l = m[0].length
replString = replString.slice(i + l)
arr[i + offset...i + offset + l] = (if l is 2 then '' else m[0][0]) +
group
arr = arr.join('').split ''
offset += i + l - group.length
return arr.join('').replace(/\\\\(\d)/, '\\$1')
class Ex
@singleton: =>
@ex ||= new Ex
@ -148,6 +166,57 @@ class Ex
sp: (args...) => @split(args...)
substitute: (range, args) ->
args = args.trimLeft()
delim = args[0]
if /[a-z]/i.test(delim)
throw new CommandError(
"Regular expressions can't be delimited by letters")
delimRE = new RegExp("[^\\\\]#{delim}")
spl = []
args_ = args[1..]
while (i = args_.search(delimRE)) isnt -1
spl.push args_[..i]
args_ = args_[i + 2..]
if args_.length is 0 and spl.length is 3
throw new CommandError('Trailing characters')
else if args_.length isnt 0
spl.push args_
if spl.length > 3
throw new CommandError('Trailing characters')
spl[1] ?= ''
spl[2] ?= ''
try
pattern = new RegExp(spl[0], spl[2])
catch e
if e.message.indexOf('Invalid flags supplied to RegExp constructor') is 0
# vim only says 'Trailing characters', but let's be more descriptive
throw new CommandError("Invalid flags: #{e.message[45..]}")
else if e.message.indexOf('Invalid regular expression: ') is 0
throw new CommandError("Invalid RegEx: #{e.message[27..]}")
else
throw e
console.log pattern, [[range[0], 0]]
buffer = atom.workspace.getActiveTextEditor().buffer
# This adds an entry to the history for each replacement
for line in [range[0]..range[1]]
console.log line
buffer.scanInRange(pattern,
[[line, 0], [line, buffer.lines[line].length]],
({match, matchText, range, stop, replace}) ->
replace(replaceGroups(match[..], spl[1]))
)
# This finds all matches in the buffer, sadly
# buffer.scanInRange(pattern,
# [[range[0], 0], [range[1], buffer.lines[range[1]]].length],
# ({match, matchText, range, stop, replace}) ->
# console.log match, matchText
# )
s: (args...) => @substitute(args...)
vsplit: (range, args) ->
args = args.trim()
filePaths = args.split(' ')