aboutsummaryrefslogtreecommitdiff
path: root/atom/packages/ex-mode/lib/ex.coffee
diff options
context:
space:
mode:
authorBen Beltran <ben@nsovocal.com>2015-07-10 11:12:25 -0500
committerBen Beltran <ben@nsovocal.com>2015-07-10 11:12:25 -0500
commit24c7594d62d8d7fbbcdb64b11ce4adc5d8e6991a (patch)
treeded312222bb108923da1820ba40b04d710d20e5b /atom/packages/ex-mode/lib/ex.coffee
parenteb786e82d170e2abc351a432ade616d6ecdeeb6b (diff)
Adds atom
Diffstat (limited to 'atom/packages/ex-mode/lib/ex.coffee')
-rw-r--r--atom/packages/ex-mode/lib/ex.coffee231
1 files changed, 231 insertions, 0 deletions
diff --git a/atom/packages/ex-mode/lib/ex.coffee b/atom/packages/ex-mode/lib/ex.coffee
new file mode 100644
index 0000000..c159534
--- /dev/null
+++ b/atom/packages/ex-mode/lib/ex.coffee
@@ -0,0 +1,231 @@
+path = require 'path'
+CommandError = require './command-error'
+
+trySave = (func) ->
+ deferred = Promise.defer()
+
+ try
+ func()
+ deferred.resolve()
+ catch error
+ if error.message.endsWith('is a directory')
+ atom.notifications.addWarning("Unable to save file: #{error.message}")
+ else if error.path?
+ if error.code is 'EACCES'
+ atom.notifications
+ .addWarning("Unable to save file: Permission denied '#{error.path}'")
+ else if error.code in ['EPERM', 'EBUSY', 'UNKNOWN', 'EEXIST']
+ atom.notifications.addWarning("Unable to save file '#{error.path}'",
+ detail: error.message)
+ else if error.code is 'EROFS'
+ atom.notifications.addWarning(
+ "Unable to save file: Read-only file system '#{error.path}'")
+ else if (errorMatch =
+ /ENOTDIR, not a directory '([^']+)'/.exec(error.message))
+ fileName = errorMatch[1]
+ atom.notifications.addWarning("Unable to save file: A directory in the "+
+ "path '#{fileName}' could not be written to")
+ else
+ throw error
+
+ deferred.promise
+
+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
+
+ @registerCommand: (name, func) =>
+ @singleton()[name] = func
+
+ quit: ->
+ atom.workspace.getActivePane().destroyActiveItem()
+
+ 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
+ else
+ atom.workspace.openURIInPane('', pane)
+
+ tabe: (args...) => @tabedit(args...)
+
+ tabnew: (args...) => @tabedit(args...)
+
+ tabclose: => @quit()
+
+ tabc: => @tabclose()
+
+ tabnext: ->
+ pane = atom.workspace.getActivePane()
+ pane.activateNextItem()
+
+ tabn: => @tabnext()
+
+ tabprevious: ->
+ pane = atom.workspace.getActivePane()
+ pane.activatePreviousItem()
+
+ tabp: => @tabprevious()
+
+ edit: (range, filePath) ->
+ filePath = filePath.trim()
+ 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()
+
+ e: (args...) => @edit(args...)
+
+ enew: ->
+ buffer = atom.workspace.getActiveTextEditor().buffer
+ buffer.setPath(undefined)
+ buffer.load()
+
+ write: (range, filePath) ->
+ filePath = filePath.trim()
+ 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
+
+ deferred.promise
+
+ w: (args...) =>
+ @write(args...)
+
+ wq: (args...) =>
+ @write(args...).then => @quit()
+
+ x: (args...) => @wq(args...)
+
+ wa: ->
+ atom.workspace.saveAll()
+
+ split: (range, args) ->
+ args = args.trim()
+ filePaths = args.split(' ')
+ filePaths = undefined if filePaths.length is 1 and filePaths[0] is ''
+ pane = atom.workspace.getActivePane()
+ if filePaths? and filePaths.length > 0
+ newPane = pane.splitUp()
+ for file in filePaths
+ do ->
+ atom.workspace.openURIInPane file, newPane
+ else
+ pane.splitUp(copyActiveItem: true)
+
+ 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
+
+ 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)
+
+ s: (args...) => @substitute(args...)
+
+ vsplit: (range, args) ->
+ args = args.trim()
+ filePaths = args.split(' ')
+ filePaths = undefined if filePaths.length is 1 and filePaths[0] is ''
+ pane = atom.workspace.getActivePane()
+ if filePaths? and filePaths.length > 0
+ newPane = pane.splitLeft()
+ for file in filePaths
+ do ->
+ atom.workspace.openURIInPane file, newPane
+ else
+ pane.splitLeft(copyActiveItem: true)
+
+ vsp: (args...) => @vsplit(args...)
+
+ delete: (range) ->
+ range = [[range[0], 0], [range[1] + 1, 0]]
+ atom.workspace.getActiveTextEditor().buffer.setTextInRange(range, '')
+
+module.exports = Ex