path = require 'path'
CommandError = require './command-error'
+fs = require 'fs-plus'
+VimOption = require './vim-option'
trySave = (func) ->
deferred = Promise.defer()
deferred.promise
+saveAs = (filePath) ->
+ editor = atom.workspace.getActiveTextEditor()
+ fs.writeFileSync(filePath, editor.getText())
+
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')
+ filePath = fs.normalize(filePath)
+
+ if path.isAbsolute(filePath)
+ filePath
+ else if atom.project.getPaths().length == 0
+ path.join(fs.normalize('~'), filePath)
+ else
+ path.join(atom.project.getPaths()[0], filePath)
+
+replaceGroups = (groups, string) ->
+ replaced = ''
+ escaped = false
+ while (char = string[0])?
+ string = string[1..]
+ if char is '\\' and not escaped
+ escaped = true
+ else if /\d/.test(char) and escaped
+ escaped = false
+ group = groups[parseInt(char)]
+ group ?= ''
+ replaced += group
+ else
+ escaped = false
+ replaced += char
+
+ replaced
class Ex
@singleton: =>
q: => @quit()
- tabedit: (range, args) ->
- args = args.trim()
- filePaths = args.split(' ')
- pane = atom.workspace.getActivePane()
- if filePaths? and filePaths.length > 0
- for file in filePaths
- do -> atom.workspace.openURIInPane file, pane
+ tabedit: (range, args) =>
+ if args.trim() isnt ''
+ @edit(range, args)
else
- atom.workspace.openURIInPane('', pane)
+ @tabnew(range, args)
tabe: (args...) => @tabedit(args...)
- tabnew: (args...) => @tabedit(args...)
+ tabnew: (range, args) =>
+ if args.trim() is ''
+ atom.workspace.open()
+ else
+ @tabedit(range, args)
- tabclose: => @quit()
+ tabclose: (args...) => @quit(args...)
tabc: => @tabclose()
edit: (range, filePath) ->
filePath = filePath.trim()
+ if filePath[0] is '!'
+ force = true
+ filePath = filePath[1..].trim()
+ else
+ force = false
+
+ editor = atom.workspace.getActiveTextEditor()
+ if editor.isModified() and not force
+ throw new CommandError('No write since last change (add ! to override)')
if filePath.indexOf(' ') isnt -1
throw new CommandError('Only one file name allowed')
- buffer = atom.workspace.getActiveTextEditor().buffer
- filePath = buffer.getPath() if filePath is ''
- buffer.setPath(getFullPath(filePath))
- buffer.load()
+
+ if filePath.length isnt 0
+ fullPath = getFullPath(filePath)
+ if fullPath is editor.getPath()
+ editor.getBuffer().reload()
+ else
+ atom.workspace.open(fullPath)
+ else
+ if editor.getPath()?
+ editor.getBuffer().reload()
+ else
+ throw new CommandError('No file name')
e: (args...) => @edit(args...)
buffer.load()
write: (range, filePath) ->
+ if filePath[0] is '!'
+ force = true
+ filePath = filePath[1..]
+ else
+ force = false
+
filePath = filePath.trim()
+ if filePath.indexOf(' ') isnt -1
+ throw new CommandError('Only one file name allowed')
+
deferred = Promise.defer()
- pane = atom.workspace.getActivePane()
editor = atom.workspace.getActiveTextEditor()
- if atom.workspace.getActiveTextEditor().getPath() isnt undefined
- if filePath.length > 0
- editorPath = editor.getPath()
- fullPath = getFullPath(filePath)
- trySave(-> editor.saveAs(fullPath))
- .then ->
- deferred.resolve()
- editor.buffer.setPath(editorPath)
- else
- trySave(-> editor.save())
- .then deferred.resolve
- else
- if filePath.length > 0
- fullPath = getFullPath(filePath)
- trySave(-> editor.saveAs(fullPath))
- .then deferred.resolve
- else
- fullPath = atom.showSaveDialogSync()
- if fullPath?
- trySave(-> editor.saveAs(fullPath))
- .then deferred.resolve
+ saved = false
+ if filePath.length isnt 0
+ fullPath = getFullPath(filePath)
+ if editor.getPath()? and (not fullPath? or editor.getPath() == fullPath)
+ # Use editor.save when no path is given or the path to the file is given
+ trySave(-> editor.save()).then(deferred.resolve)
+ saved = true
+ else if not fullPath?
+ fullPath = atom.showSaveDialogSync()
+
+ if not saved and fullPath?
+ if not force and fs.existsSync(fullPath)
+ throw new CommandError("File exists (add ! to override)")
+ trySave(-> saveAs(fullPath)).then(deferred.resolve)
deferred.promise
wq: (args...) =>
@write(args...).then => @quit()
- x: (args...) => @wq(args...)
+ xit: (args...) => @wq(args...)
wa: ->
atom.workspace.saveAll()
throw new CommandError('Trailing characters')
spl[1] ?= ''
spl[2] ?= ''
+ notDelimRE = new RegExp("\\\\#{delim}", 'g')
+ spl[0] = spl[0].replace(notDelimRE, delim)
+ spl[1] = spl[1].replace(notDelimRE, delim)
try
pattern = new RegExp(spl[0], spl[2])
throw e
buffer = atom.workspace.getActiveTextEditor().buffer
- cp = buffer.history.createCheckpoint()
- for line in [range[0]..range[1]]
- buffer.scanInRange(pattern,
- [[line, 0], [line, buffer.lines[line].length]],
- ({match, matchText, range, stop, replace}) ->
- replace(replaceGroups(match[..], spl[1]))
- )
- buffer.history.groupChangesSinceCheckpoint(cp)
+ atom.workspace.getActiveTextEditor().transact ->
+ for line in [range[0]..range[1]]
+ buffer.scanInRange(pattern,
+ [[line, 0], [line, buffer.lines[line].length]],
+ ({match, matchText, range, stop, replace}) ->
+ replace(replaceGroups(match[..], spl[1]))
+ )
s: (args...) => @substitute(args...)
range = [[range[0], 0], [range[1] + 1, 0]]
atom.workspace.getActiveTextEditor().buffer.setTextInRange(range, '')
+ set: (range, args) ->
+ args = args.trim()
+ if args == ""
+ throw new CommandError("No option specified")
+ options = args.split(' ')
+ for option in options
+ do ->
+ if option.includes("=")
+ nameValPair = option.split("=")
+ if (nameValPair.length != 2)
+ throw new CommandError("Wrong option format. [name]=[value] format is expected")
+ optionName = nameValPair[0]
+ optionValue = nameValPair[1]
+ optionProcessor = VimOption.singleton()[optionName]
+ if not optionProcessor?
+ throw new CommandError("No such option: #{optionName}")
+ optionProcessor(optionValue)
+ else
+ optionProcessor = VimOption.singleton()[option]
+ if not optionProcessor?
+ throw new CommandError("No such option: #{option}")
+ optionProcessor()
+
module.exports = Ex