1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-12-24 14:23:34 +03:00

GH-227 It compiles, it compiles

This commit is contained in:
Tae Won Ha 2016-09-25 17:50:33 +02:00
parent d29c67064e
commit 0f7b564667
No known key found for this signature in database
GPG Key ID: E40743465B5B8B44
50 changed files with 1005 additions and 1007 deletions

View File

@ -1,3 +1,3 @@
github "ReactiveX/RxSwift" == 2.6.0
github "ReactiveX/RxSwift" "3.0.0-beta.1"
github "PureLayout/PureLayout" == 3.0.2
github "eonil/FileSystemEvents" "master"

View File

@ -1 +1 @@
github "Quick/Nimble" == 4.1.0
github "Quick/Nimble" == 5.0.0

View File

@ -1,4 +1,4 @@
github "eonil/FileSystemEvents" "01f622d3b446612d573b1035b46afb7a6eee0240"
github "Quick/Nimble" "v4.1.0"
github "eonil/FileSystemEvents" "aa5c6af1fd35939f9aca3b9eba3b672bfa549b3a"
github "Quick/Nimble" "v5.0.0"
github "PureLayout/PureLayout" "v3.0.2"
github "ReactiveX/RxSwift" "2.6.0"
github "ReactiveX/RxSwift" "3.0.0-beta.1"

View File

@ -30,7 +30,7 @@ extension NSView {
/// - Returns: Rects currently being drawn
/// - Warning: Call only in drawRect()
func rectsBeingDrawn() -> [CGRect] {
var rectsPtr: UnsafePointer<CGRect> = nil
var rectsPtr: UnsafePointer<CGRect>? = nil
var count: Int = 0
self.getRectsBeingDrawn(&rectsPtr, count: &count)

View File

@ -7,11 +7,11 @@ import Cocoa
class ColorUtils {
static func colorIgnoringAlpha(rgb: UInt32) -> NSColor {
static func colorIgnoringAlpha(_ rgb: UInt32) -> NSColor {
let red = (CGFloat((rgb >> 16) & 0xFF)) / 255.0;
let green = (CGFloat((rgb >> 8) & 0xFF)) / 255.0;
let blue = (CGFloat((rgb ) & 0xFF)) / 255.0;
return NSColor(SRGBRed: red, green: green, blue: blue, alpha: 1.0)
return NSColor(srgbRed: red, green: green, blue: blue, alpha: 1.0)
}
}

View File

@ -5,11 +5,11 @@
import Cocoa
public class DispatchUtils {
open class DispatchUtils {
private static let qDispatchMainQueue = dispatch_get_main_queue()
fileprivate static let qDispatchMainQueue = DispatchQueue.main
public static func gui(call: () -> Void) {
dispatch_async(DispatchUtils.qDispatchMainQueue, call)
open static func gui(_ call: @escaping () -> Void) {
DispatchUtils.qDispatchMainQueue.async(execute: call)
}
}

View File

@ -6,7 +6,7 @@
import Cocoa
struct Cell: CustomStringConvertible {
private let attributes: CellAttributes
fileprivate let attributes: CellAttributes
let string: String
var marked: Bool
@ -72,11 +72,11 @@ struct Region: CustomStringConvertible {
return "Region<\(self.top)...\(self.bottom):\(self.left)...\(self.right)>"
}
var rowRange: Range<Int> {
var rowRange: CountableClosedRange<Int> {
return self.top...self.bottom
}
var columnRange: Range<Int> {
var columnRange: CountableClosedRange<Int> {
return self.left...self.right
}
}
@ -84,10 +84,10 @@ struct Region: CustomStringConvertible {
/// Almost a verbatim copy of ugrid.c of NeoVim
class Grid: CustomStringConvertible {
private(set) var region = Region.zero
private(set) var size = Size.zero
private(set) var putPosition = Position.zero
private(set) var screenCursor = Position.zero
fileprivate(set) var region = Region.zero
fileprivate(set) var size = Size.zero
fileprivate(set) var putPosition = Position.zero
fileprivate(set) var screenCursor = Position.zero
var foreground = qDefaultForeground
var background = qDefaultBackground
@ -95,11 +95,11 @@ class Grid: CustomStringConvertible {
var dark = false
var attrs: CellAttributes = CellAttributes(
fontTrait: .None,
fontTrait: .none,
foreground: qDefaultForeground, background: qDefaultBackground, special: qDefaultSpecial
)
private(set) var cells: [[Cell]] = []
fileprivate(set) var cells: [[Cell]] = []
var hasData: Bool {
return !self.cells.isEmpty
@ -109,16 +109,16 @@ class Grid: CustomStringConvertible {
return self.cells.reduce("<<< Grid\n") { $1.reduce($0) { $0 + $1.description } + "\n" } + ">>>"
}
func resize(size: Size) {
func resize(_ size: Size) {
self.region = Region(top: 0, bottom: size.height - 1, left: 0, right: size.width - 1)
self.size = size
self.putPosition = Position.zero
let emptyCellAttrs = CellAttributes(fontTrait: .None,
let emptyCellAttrs = CellAttributes(fontTrait: .none,
foreground: self.foreground, background: self.background, special: self.special)
let emptyRow = Array(count: size.width, repeatedValue: Cell(string: " ", attrs: emptyCellAttrs))
self.cells = Array(count: size.height, repeatedValue: emptyRow)
let emptyRow = Array(repeating: Cell(string: " ", attrs: emptyCellAttrs), count: size.width)
self.cells = Array(repeating: emptyRow, count: size.height)
}
func clear() {
@ -132,11 +132,11 @@ class Grid: CustomStringConvertible {
)
}
func setScrollRegion(region: Region) {
func setScrollRegion(_ region: Region) {
self.region = region
}
func scroll(count: Int) {
func scroll(_ count: Int) {
var start, stop, step : Int
if count > 0 {
start = self.region.top;
@ -150,8 +150,8 @@ class Grid: CustomStringConvertible {
// copy cell data
let rangeWithinRow = self.region.left...self.region.right
for i in start.stride(to: stop, by: step) {
self.cells[i].replaceRange(rangeWithinRow, with: self.cells[i + count][rangeWithinRow])
for i in stride(from: start, to: stop, by: step) {
self.cells[i].replaceSubrange(rangeWithinRow, with: self.cells[i + count][rangeWithinRow])
}
// clear cells in the emptied region,
@ -166,15 +166,15 @@ class Grid: CustomStringConvertible {
self.clearRegion(Region(top: clearTop, bottom: clearBottom, left: self.region.left, right: self.region.right))
}
func goto(position: Position) {
func goto(_ position: Position) {
self.putPosition = position
}
func moveCursor(position: Position) {
func moveCursor(_ position: Position) {
self.screenCursor = position
}
func put(string: String) {
func put(_ string: String) {
// FIXME: handle the following situation:
// |abcde | <- type
// =>
@ -187,18 +187,18 @@ class Grid: CustomStringConvertible {
self.putPosition.column += 1
}
func putMarkedText(string: String) {
func putMarkedText(_ string: String) {
// NOTE: Maybe there's a better way to indicate marked text than inverting...
self.cells[self.putPosition.row][self.putPosition.column] = Cell(string: string, attrs: self.attrs, marked: true)
self.putPosition.column += 1
}
func unmarkCell(position: Position) {
func unmarkCell(_ position: Position) {
// NSLog("\(#function): \(position)")
self.cells[position.row][position.column].marked = false
}
func singleIndexFrom(position: Position) -> Int {
func singleIndexFrom(_ position: Position) -> Int {
return position.row * self.size.width + position.column
}
@ -215,7 +215,7 @@ class Grid: CustomStringConvertible {
}
var left = 0
for idx in (0..<column).reverse() {
for idx in (0..<column).reversed() {
let cell = self.cells[row][idx]
if cell.string == " " {
left = idx + 1
@ -235,14 +235,14 @@ class Grid: CustomStringConvertible {
return Region(top: row, bottom: row, left: left, right: right)
}
func positionFromSingleIndex(idx: Int) -> Position {
func positionFromSingleIndex(_ idx: Int) -> Position {
let row = Int(floor(Double(idx) / Double(self.size.width)))
let column = idx - row * self.size.width
return Position(row: row, column: column)
}
func isCellEmpty(position: Position) -> Bool {
func isCellEmpty(_ position: Position) -> Bool {
guard self.isSane(position: position) else {
return false
}
@ -254,44 +254,44 @@ class Grid: CustomStringConvertible {
return false
}
func isPreviousCellEmpty(position: Position) -> Bool {
func isPreviousCellEmpty(_ position: Position) -> Bool {
return self.isCellEmpty(self.previousCellPosition(position))
}
func isNextCellEmpty(position: Position) -> Bool {
func isNextCellEmpty(_ position: Position) -> Bool {
return self.isCellEmpty(self.nextCellPosition(position))
}
func previousCellPosition(position: Position) -> Position {
func previousCellPosition(_ position: Position) -> Position {
return Position(row: position.row, column: max(position.column - 1, 0))
}
func nextCellPosition(position: Position) -> Position {
func nextCellPosition(_ position: Position) -> Position {
return Position(row: position.row, column: min(position.column + 1, self.size.width - 1))
}
func cellForSingleIndex(idx: Int) -> Cell {
func cellForSingleIndex(_ idx: Int) -> Cell {
let position = self.positionFromSingleIndex(idx)
return self.cells[position.row][position.column]
}
private func clearRegion(region: Region) {
fileprivate func clearRegion(_ region: Region) {
// FIXME: sometimes clearRegion gets called without first resizing the Grid. Should we handle this?
guard self.hasData else {
return
}
let clearedAttrs = CellAttributes(fontTrait: .None,
let clearedAttrs = CellAttributes(fontTrait: .none,
foreground: self.foreground, background: self.background, special: self.special)
let clearedCell = Cell(string: " ", attrs: clearedAttrs)
let clearedRow = Array(count: region.right - region.left + 1, repeatedValue: clearedCell)
let clearedRow = Array(repeating: clearedCell, count: region.right - region.left + 1)
for i in region.top...region.bottom {
self.cells[i].replaceRange(region.left...region.right, with: clearedRow)
self.cells[i].replaceSubrange(region.left...region.right, with: clearedRow)
}
}
private func isSane(position position: Position) -> Bool {
fileprivate func isSane(position: Position) -> Bool {
guard position.row < self.size.height && position.column < self.size.width else {
return false
}

View File

@ -58,7 +58,7 @@ class KeyUtils {
NSF35FunctionKey: "F35",
]
static func isSpecial(key key: String) -> Bool {
static func isSpecial(key: String) -> Bool {
guard key.characters.count == 1 else {
return false
}
@ -70,7 +70,7 @@ class KeyUtils {
return false
}
static func namedKeyFrom(key key: String) -> String {
static func namedKeyFrom(key: String) -> String {
if let firstChar = key.utf16.first {
if KeyUtils.specialKeys.keys.contains(Int(firstChar)) {
return KeyUtils.specialKeys[Int(firstChar)]!

View File

@ -9,7 +9,7 @@ import Cocoa
private struct RowRun: CustomStringConvertible {
let row: Int
let range: Range<Int>
let range: CountableClosedRange<Int>
let attrs: CellAttributes
var description: String {
@ -17,7 +17,7 @@ private struct RowRun: CustomStringConvertible {
}
}
public class NeoVimView: NSView, NSUserInterfaceValidations {
open class NeoVimView: NSView, NSUserInterfaceValidations {
public struct Config {
let useInteractiveZsh: Bool
@ -27,29 +27,29 @@ public class NeoVimView: NSView, NSUserInterfaceValidations {
}
}
public static let minFontSize = CGFloat(4)
public static let maxFontSize = CGFloat(128)
public static let defaultFont = NSFont.userFixedPitchFontOfSize(13)!
open static let minFontSize = CGFloat(4)
open static let maxFontSize = CGFloat(128)
open static let defaultFont = NSFont.userFixedPitchFont(ofSize: 13)!
public let uuid = NSUUID().UUIDString
public weak var delegate: NeoVimViewDelegate?
open let uuid = UUID().uuidString
open weak var delegate: NeoVimViewDelegate?
public private(set) var mode = Mode.Normal
open fileprivate(set) var mode = Mode.Normal
public var usesLigatures = false {
open var usesLigatures = false {
didSet {
self.drawer.usesLigatures = self.usesLigatures
self.needsDisplay = true
}
}
public var font: NSFont {
open var font: NSFont {
get {
return self._font
}
set {
guard newValue.fixedPitch else {
guard newValue.isFixedPitch else {
return
}
@ -68,59 +68,56 @@ public class NeoVimView: NSView, NSUserInterfaceValidations {
}
}
public var cwd: NSURL {
open var cwd: URL {
get {
return NSURL(fileURLWithPath: self.agent.vimCommandOutput("silent pwd"))
return URL(fileURLWithPath: self.agent.vimCommandOutput("silent pwd"))
}
set {
guard let path = newValue.path else {
return
}
let path = newValue.path
let escapedCwd = self.agent.escapedFileName(path)
self.agent.vimCommand("silent cd \(escapedCwd)")
}
}
private var _font = NeoVimView.defaultFont
fileprivate var _font = NeoVimView.defaultFont
private let agent: NeoVimAgent
private let drawer: TextDrawer
private let fontManager = NSFontManager.sharedFontManager()
private let pasteboard = NSPasteboard.generalPasteboard()
fileprivate let agent: NeoVimAgent
fileprivate let drawer: TextDrawer
fileprivate let fontManager = NSFontManager.shared()
fileprivate let pasteboard = NSPasteboard.general()
private let grid = Grid()
fileprivate let grid = Grid()
private var markedText: String?
fileprivate var markedText: String?
/// We store the last marked text because Cocoa's text input system does the following:
/// -> hanja popup -> insertText() -> attributedSubstring...() -> setMarkedText() -> ...
/// We want to return "" in attributedSubstring...()
private var lastMarkedText: String?
fileprivate var lastMarkedText: String?
private var markedPosition = Position.null
private var keyDownDone = true
fileprivate var markedPosition = Position.null
fileprivate var keyDownDone = true
private var lastClickedCellPosition = Position.null
fileprivate var lastClickedCellPosition = Position.null
private var xOffset = CGFloat(0)
private var yOffset = CGFloat(0)
private var cellSize = CGSize.zero
private var descent = CGFloat(0)
private var leading = CGFloat(0)
fileprivate var xOffset = CGFloat(0)
fileprivate var yOffset = CGFloat(0)
fileprivate var cellSize = CGSize.zero
fileprivate var descent = CGFloat(0)
fileprivate var leading = CGFloat(0)
private let maxScrollDeltaX = 30
private let maxScrollDeltaY = 30
private let scrollLimiterX = CGFloat(20)
private let scrollLimiterY = CGFloat(20)
private var scrollGuardCounterX = 5
private var scrollGuardCounterY = 5
private let scrollGuardYield = 5
fileprivate let maxScrollDeltaX = 30
fileprivate let maxScrollDeltaY = 30
fileprivate let scrollLimiterX = CGFloat(20)
fileprivate let scrollLimiterY = CGFloat(20)
fileprivate var scrollGuardCounterX = 5
fileprivate var scrollGuardCounterY = 5
fileprivate let scrollGuardYield = 5
private var isCurrentlyPinching = false
private var pinchTargetScale = CGFloat(1)
private var pinchImage = NSImage()
fileprivate var isCurrentlyPinching = false
fileprivate var pinchTargetScale = CGFloat(1)
fileprivate var pinchImage = NSImage()
public init(frame rect: NSRect, config: Config) {
self.drawer = TextDrawer(font: self._font, useLigatures: false)
@ -142,7 +139,7 @@ public class NeoVimView: NSView, NSUserInterfaceValidations {
DispatchUtils.gui {
if noErrorDuringInitialization == false {
let alert = NSAlert()
alert.alertStyle = .WarningAlertStyle
alert.alertStyle = .warning
alert.messageText = "Error during initialization"
alert.informativeText = "There was an error during the initialization of NeoVim. "
+ "Use :messages to view the error messages."
@ -161,7 +158,7 @@ public class NeoVimView: NSView, NSUserInterfaceValidations {
fatalError("init(coder:) has not been implemented")
}
@IBAction public func debug1(sender: AnyObject!) {
@IBAction open func debug1(_ sender: AnyObject!) {
NSLog("DEBUG 1 - Start")
NSLog("\(self.agent.vimCommandOutput("silent echo $PATH"))")
NSLog("\(self.agent.vimCommandOutput("silent pwd"))")
@ -188,10 +185,10 @@ extension NeoVimView {
self.exec(command: "tabe")
}
public func open(urls urls: [NSURL]) {
public func open(urls: [URL]) {
let currentBufferIsTransient = self.agent.buffers().filter { $0.current }.first?.transient ?? false
urls.enumerate().forEach { (idx, url) in
urls.enumerated().forEach { (idx, url) in
if idx == 0 && currentBufferIsTransient {
self.open(url, cmd: "e")
} else {
@ -200,11 +197,11 @@ extension NeoVimView {
}
}
public func openInNewTab(urls urls: [NSURL]) {
public func openInNewTab(urls: [URL]) {
urls.forEach { self.open($0, cmd: "tabe") }
}
public func openInCurrentTab(url url: NSURL) {
public func openInCurrentTab(url: URL) {
self.open(url, cmd: "e")
}
@ -216,11 +213,8 @@ extension NeoVimView {
self.exec(command: "w")
}
public func saveCurrentTab(url url: NSURL) {
guard let path = url.path else {
return
}
public func saveCurrentTab(url: URL) {
let path = url.path
let escapedFileName = self.agent.escapedFileName(path)
self.exec(command: "w \(escapedFileName)")
}
@ -240,7 +234,7 @@ extension NeoVimView {
/// Does the following
/// - `Mode.Normal`: `:command<CR>`
/// - else: `:<Esc>:command<CR>`
private func exec(command cmd: String) {
fileprivate func exec(command cmd: String) {
switch self.mode {
case .Normal:
self.agent.vimInput(":\(cmd)<CR>")
@ -249,11 +243,8 @@ extension NeoVimView {
}
}
private func open(url: NSURL, cmd: String) {
guard let path = url.path else {
return
}
fileprivate func open(_ url: URL, cmd: String) {
let path = url.path
let escapedFileName = self.agent.escapedFileName(path)
self.exec(command: "\(cmd) \(escapedFileName)")
}
@ -262,7 +253,7 @@ extension NeoVimView {
// MARK: - Resizing
extension NeoVimView {
override public func setFrameSize(newSize: NSSize) {
override open func setFrameSize(_ newSize: NSSize) {
super.setFrameSize(newSize)
// initial resizing is done when grid has data
@ -281,22 +272,22 @@ extension NeoVimView {
self.resizeNeoVimUiTo(size: newSize)
}
override public func viewDidEndLiveResize() {
override open func viewDidEndLiveResize() {
super.viewDidEndLiveResize()
self.resizeNeoVimUiTo(size: self.bounds.size)
}
private func resizeNeoVimUiTo(size size: CGSize) {
fileprivate func resizeNeoVimUiTo(size: CGSize) {
// NSLog("\(#function): \(size)")
let discreteSize = self.discreteSize(size: size)
self.xOffset = floor((size.width - self.cellSize.width * CGFloat(discreteSize.width)) / 2)
self.yOffset = floor((size.height - self.cellSize.height * CGFloat(discreteSize.height)) / 2)
self.agent.resizeToWidth(Int32(discreteSize.width), height: Int32(discreteSize.height))
self.agent.resize(toWidth: Int32(discreteSize.width), height: Int32(discreteSize.height))
}
private func discreteSize(size size: CGSize) -> Size {
fileprivate func discreteSize(size: CGSize) -> Size {
return Size(width: Int(floor(size.width / self.cellSize.width)),
height: Int(floor(size.height / self.cellSize.height)))
}
@ -305,42 +296,42 @@ extension NeoVimView {
// MARK: - Drawing
extension NeoVimView {
override public func drawRect(dirtyUnionRect: NSRect) {
override open func draw(_ dirtyUnionRect: NSRect) {
guard self.grid.hasData else {
return
}
if self.inLiveResize {
NSColor.windowBackgroundColor().set()
NSColor.windowBackgroundColor.set()
dirtyUnionRect.fill()
let boundsSize = self.bounds.size
let discreteSize = self.discreteSize(size: boundsSize)
let displayStr = "\(discreteSize.width) × \(discreteSize.height)"
let attrs = [ NSFontAttributeName: NSFont.systemFontOfSize(24) ]
let attrs = [ NSFontAttributeName: NSFont.systemFont(ofSize: 24) ]
let size = displayStr.sizeWithAttributes(attrs)
let size = displayStr.size(withAttributes: attrs)
let x = (boundsSize.width - size.width) / 2
let y = (boundsSize.height - size.height) / 2
displayStr.drawAtPoint(CGPoint(x: x, y: y), withAttributes: attrs)
displayStr.draw(at: CGPoint(x: x, y: y), withAttributes: attrs)
return
}
// NSLog("\(#function): \(dirtyUnionRect)")
let context = NSGraphicsContext.currentContext()!.CGContext
let context = NSGraphicsContext.current()!.cgContext
if self.isCurrentlyPinching {
let boundsSize = self.bounds.size
let targetSize = CGSize(width: boundsSize.width * self.pinchTargetScale,
height: boundsSize.height * self.pinchTargetScale)
self.pinchImage.drawInRect(CGRect(origin: self.bounds.origin, size: targetSize))
self.pinchImage.draw(in: CGRect(origin: self.bounds.origin, size: targetSize))
return
}
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextSetTextDrawingMode(context, .Fill);
context.textMatrix = CGAffineTransform.identity;
context.setTextDrawingMode(.fill);
let dirtyRects = self.rectsBeingDrawn()
// NSLog("\(dirtyRects)")
@ -349,7 +340,7 @@ extension NeoVimView {
self.drawCursor(context: context)
}
private func draw(rowRun rowFrag: RowRun, context: CGContext) {
fileprivate func draw(rowRun rowFrag: RowRun, context: CGContext) {
// For background drawing we don't filter out the put(0, 0)s: in some cases only the put(0, 0)-cells should be
// redrawn. => FIXME: probably we have to consider this also when drawing further down, ie when the range starts
// with '0'...
@ -368,13 +359,13 @@ extension NeoVimView {
let string = self.grid.cells[rowFrag.row][rowFrag.range].reduce("") { $0 + $1.string }
let glyphPositions = positions.map { CGPoint(x: $0.x, y: $0.y + self.descent + self.leading) }
self.drawer.drawString(string,
positions: UnsafeMutablePointer(glyphPositions), positionsCount: positions.count,
self.drawer.draw(string,
positions: UnsafeMutablePointer(mutating: glyphPositions), positionsCount: positions.count,
highlightAttrs: rowFrag.attrs,
context: context)
}
private func cursorRegion() -> Region {
fileprivate func cursorRegion() -> Region {
let cursorPosition = self.mode == .Cmdline ? self.grid.putPosition : self.grid.screenCursor
// NSLog("\(#function): \(cursorPosition)")
@ -393,7 +384,7 @@ extension NeoVimView {
return cursorRegion
}
private func drawCursor(context context: CGContext) {
fileprivate func drawCursor(context: CGContext) {
// FIXME: for now do some rudimentary cursor drawing
let cursorRegion = self.cursorRegion()
let cursorRow = cursorRegion.top
@ -409,7 +400,7 @@ extension NeoVimView {
self.draw(rowRun: rowRun, context: context)
}
private func drawBackground(positions positions: [CGPoint], background: UInt32) {
fileprivate func drawBackground(positions: [CGPoint], background: UInt32) {
ColorUtils.colorIgnoringAlpha(background).set()
// NSColor(calibratedRed: CGFloat(drand48()), green: CGFloat(drand48()), blue: CGFloat(drand48()), alpha: 1.0).set()
let backgroundRect = CGRect(
@ -419,9 +410,9 @@ extension NeoVimView {
backgroundRect.fill()
}
private func rowRunIntersecting(rects rects: [CGRect]) -> [RowRun] {
fileprivate func rowRunIntersecting(rects: [CGRect]) -> [RowRun] {
return rects
.map { rect -> (Range<Int>, Range<Int>) in
.map { rect -> (CountableClosedRange<Int>, CountableClosedRange<Int>) in
// Get all Regions that intersects with the given rects. There can be overlaps between the Regions, but for the
// time being we ignore them; probably not necessary to optimize them away.
let region = self.regionFor(rect: rect)
@ -431,17 +422,17 @@ extension NeoVimView {
.flatMap { $0 } // Flattened RowRuns for all Regions.
}
private func rowRunsFor(rowRange rowRange: Range<Int>, columnRange: Range<Int>) -> [RowRun] {
fileprivate func rowRunsFor(rowRange: CountableClosedRange<Int>, columnRange: CountableClosedRange<Int>) -> [RowRun] {
return rowRange
.map { (row) -> [RowRun] in
let rowCells = self.grid.cells[row]
let startIdx = columnRange.startIndex
let startIdx = columnRange.lowerBound
var result = [ RowRun(row: row, range: startIdx...startIdx, attrs: rowCells[startIdx].attrs) ]
columnRange.forEach { idx in
if rowCells[idx].attrs == result.last!.attrs {
let last = result.popLast()!
result.append(RowRun(row: row, range: last.range.startIndex...idx, attrs: last.attrs))
result.append(RowRun(row: row, range: last.range.lowerBound...idx, attrs: last.attrs))
} else {
result.append(RowRun(row: row, range: idx...idx, attrs: rowCells[idx].attrs))
}
@ -452,7 +443,7 @@ extension NeoVimView {
.flatMap { $0 } // Flattened RowRuns for a Region.
}
private func regionFor(rect rect: CGRect) -> Region {
fileprivate func regionFor(rect: CGRect) -> Region {
let cellWidth = self.cellSize.width
let cellHeight = self.cellSize.height
@ -472,22 +463,22 @@ extension NeoVimView {
return Region(top: rowStart, bottom: rowEnd, left: columnStart, right: columnEnd)
}
private func pointInViewFor(position position: Position) -> CGPoint {
fileprivate func pointInViewFor(position: Position) -> CGPoint {
return self.pointInViewFor(row: position.row, column: position.column)
}
private func pointInViewFor(row row: Int, column: Int) -> CGPoint {
fileprivate func pointInViewFor(row: Int, column: Int) -> CGPoint {
return CGPoint(
x: self.xOffset + CGFloat(column) * self.cellSize.width,
y: self.bounds.size.height - self.yOffset - CGFloat(row) * self.cellSize.height - self.cellSize.height
)
}
private func cellRectFor(row row: Int, column: Int) -> CGRect {
fileprivate func cellRectFor(row: Int, column: Int) -> CGRect {
return CGRect(origin: self.pointInViewFor(row: row, column: column), size: self.cellSize)
}
private func regionRectFor(region region: Region) -> CGRect {
fileprivate func regionRectFor(region: Region) -> CGRect {
let top = CGFloat(region.top)
let bottom = CGFloat(region.bottom)
let left = CGFloat(region.left)
@ -507,35 +498,39 @@ extension NeoVimView {
)
}
private func wrapNamedKeys(string: String) -> String {
fileprivate func wrapNamedKeys(_ string: String) -> String {
return "<\(string)>"
}
private func vimPlainString(string: String) -> String {
return string.stringByReplacingOccurrencesOfString("<", withString: self.wrapNamedKeys("lt"))
fileprivate func vimPlainString(_ string: String) -> String {
return string.replacingOccurrences(of: "<", with: self.wrapNamedKeys("lt"))
}
}
// MARK: - NSUserInterfaceValidationsProtocol
extension NeoVimView {
public func validateUserInterfaceItem(item: NSValidatedUserInterfaceItem) -> Bool {
public func validateUserInterfaceItem(_ item: NSValidatedUserInterfaceItem) -> Bool {
let canUndoOrRedo = self.mode == .Insert || self.mode == .Replace || self.mode == .Normal || self.mode == .Visual
let canCopyOrCut = self.mode == .Normal || self.mode == .Visual
let canPaste = self.pasteboard.stringForType(NSPasteboardTypeString) != nil
let canPaste = self.pasteboard.string(forType: NSPasteboardTypeString) != nil
let canDelete = self.mode == .Visual || self.mode == .Normal
let canSelectAll = self.mode == .Insert || self.mode == .Replace || self.mode == .Normal || self.mode == .Visual
switch item.action() {
case NSSelectorFromString("undo:"), NSSelectorFromString("redo:"):
guard let action = item.action else {
return true
}
switch action {
case Selector("undo:"), Selector("redo:"):
return canUndoOrRedo
case NSSelectorFromString("copy:"), NSSelectorFromString("cut:"):
case Selector("copy:"), Selector("cut:"):
return canCopyOrCut
case NSSelectorFromString("paste:"):
case Selector("paste:"):
return canPaste
case NSSelectorFromString("delete:"):
case Selector("delete:"):
return canDelete
case NSSelectorFromString("selectAll:"):
case Selector("selectAll:"):
return canSelectAll
default:
return true
@ -546,7 +541,7 @@ extension NeoVimView {
// MARK: - Edit Menu Items
extension NeoVimView {
@IBAction func undo(sender: AnyObject!) {
@IBAction func undo(_ sender: AnyObject!) {
switch self.mode {
case .Insert, .Replace:
self.agent.vimInput("<Esc>ui")
@ -557,7 +552,7 @@ extension NeoVimView {
}
}
@IBAction func redo(sender: AnyObject!) {
@IBAction func redo(_ sender: AnyObject!) {
switch self.mode {
case .Insert, .Replace:
self.agent.vimInput("<Esc><C-r>i")
@ -568,7 +563,7 @@ extension NeoVimView {
}
}
@IBAction func cut(sender: AnyObject!) {
@IBAction func cut(_ sender: AnyObject!) {
switch self.mode {
case .Visual, .Normal:
self.agent.vimInput("\"+d")
@ -577,7 +572,7 @@ extension NeoVimView {
}
}
@IBAction func copy(sender: AnyObject!) {
@IBAction func copy(_ sender: AnyObject!) {
switch self.mode {
case .Visual, .Normal:
self.agent.vimInput("\"+y")
@ -586,8 +581,8 @@ extension NeoVimView {
}
}
@IBAction func paste(sender: AnyObject!) {
guard let content = self.pasteboard.stringForType(NSPasteboardTypeString) else {
@IBAction func paste(_ sender: AnyObject!) {
guard let content = self.pasteboard.string(forType: NSPasteboardTypeString) else {
return
}
@ -599,7 +594,7 @@ extension NeoVimView {
}
}
@IBAction func delete(sender: AnyObject!) {
@IBAction func delete(_ sender: AnyObject!) {
switch self.mode {
case .Normal, .Visual:
self.agent.vimInput("x")
@ -608,7 +603,7 @@ extension NeoVimView {
}
}
@IBAction public override func selectAll(sender: AnyObject?) {
@IBAction open override func selectAll(_ sender: Any?) {
switch self.mode {
case .Insert, .Visual:
self.agent.vimInput("<Esc>ggVG")
@ -621,10 +616,10 @@ extension NeoVimView {
// MARK: - Key Events
extension NeoVimView: NSTextInputClient {
override public func keyDown(event: NSEvent) {
override open func keyDown(with event: NSEvent) {
self.keyDownDone = false
let context = NSTextInputContext.currentInputContext()!
let context = NSTextInputContext.current()!
let cocoaHandledEvent = context.handleEvent(event)
if self.keyDownDone && cocoaHandledEvent {
return
@ -633,10 +628,10 @@ extension NeoVimView: NSTextInputClient {
// NSLog("\(#function): \(event)")
let modifierFlags = event.modifierFlags
let capslock = modifierFlags.contains(.AlphaShiftKeyMask)
let shift = modifierFlags.contains(.ShiftKeyMask)
let capslock = modifierFlags.contains(.capsLock)
let shift = modifierFlags.contains(.shift)
let chars = event.characters!
let charsIgnoringModifiers = shift || capslock ? event.charactersIgnoringModifiers!.lowercaseString
let charsIgnoringModifiers = shift || capslock ? event.charactersIgnoringModifiers!.lowercased()
: event.charactersIgnoringModifiers!
if KeyUtils.isSpecial(key: charsIgnoringModifiers) {
@ -656,7 +651,7 @@ extension NeoVimView: NSTextInputClient {
self.keyDownDone = true
}
public func insertText(aString: AnyObject, replacementRange: NSRange) {
public func insertText(_ aString: Any, replacementRange: NSRange) {
// NSLog("\(#function): \(replacementRange): '\(aString)'")
switch aString {
@ -675,14 +670,14 @@ extension NeoVimView: NSTextInputClient {
self.keyDownDone = true
}
public override func doCommandBySelector(aSelector: Selector) {
open override func doCommand(by aSelector: Selector) {
// NSLog("\(#function): \(aSelector)");
// FIXME: handle when -> delete
if self.respondsToSelector(aSelector) {
if self.responds(to: aSelector) {
Swift.print("\(#function): calling \(aSelector)")
self.performSelector(aSelector, withObject: self)
self.perform(aSelector, with: self)
self.keyDownDone = true
return
}
@ -691,7 +686,7 @@ extension NeoVimView: NSTextInputClient {
self.keyDownDone = false
}
public func setMarkedText(aString: AnyObject, selectedRange: NSRange, replacementRange: NSRange) {
public func setMarkedText(_ aString: Any, selectedRange: NSRange, replacementRange: NSRange) {
if self.markedText == nil {
self.markedPosition = self.grid.putPosition
}
@ -707,7 +702,7 @@ extension NeoVimView: NSTextInputClient {
case let attributedString as NSAttributedString:
self.markedText = attributedString.string
default:
self.markedText = String(aString) // should not occur
self.markedText = String(describing: aString) // should not occur
}
// NSLog("\(#function): \(self.markedText), \(selectedRange), \(replacementRange)")
@ -723,7 +718,7 @@ extension NeoVimView: NSTextInputClient {
self.keyDownDone = true
// TODO: necessary?
self.setNeedsDisplayInRect(self.cellRectFor(row: self.grid.putPosition.row, column: self.grid.putPosition.column))
self.setNeedsDisplay(self.cellRectFor(row: self.grid.putPosition.row, column: self.grid.putPosition.column))
}
/// Return the current selection (or the position of the cursor with empty-length range). For example when you enter
@ -761,7 +756,7 @@ extension NeoVimView: NSTextInputClient {
// FIXME: take into account the "return nil"-case
// FIXME: just fix me, PLEASE...
public func attributedSubstringForProposedRange(aRange: NSRange, actualRange: NSRangePointer) -> NSAttributedString? {
public func attributedSubstring(forProposedRange aRange: NSRange, actualRange: NSRangePointer?) -> NSAttributedString? {
// NSLog("\(#function): \(aRange), \(actualRange[0])")
if aRange.location == NSNotFound {
// NSLog("\(#function): range not found: returning nil")
@ -789,28 +784,28 @@ extension NeoVimView: NSTextInputClient {
return []
}
public func firstRectForCharacterRange(aRange: NSRange, actualRange: NSRangePointer) -> NSRect {
public func firstRect(forCharacterRange aRange: NSRange, actualRange: NSRangePointer?) -> NSRect {
let position = self.grid.positionFromSingleIndex(aRange.location)
// NSLog("\(#function): \(aRange),\(actualRange[0]) -> \(position.row):\(position.column)")
let resultInSelf = self.cellRectFor(row: position.row, column: position.column)
let result = self.window?.convertRectToScreen(self.convertRect(resultInSelf, toView: nil))
let result = self.window?.convertToScreen(self.convert(resultInSelf, to: nil))
return result!
}
public func characterIndexForPoint(aPoint: NSPoint) -> Int {
public func characterIndex(for aPoint: NSPoint) -> Int {
// NSLog("\(#function): \(aPoint)")
return 1
}
private func vimModifierFlags(modifierFlags: NSEventModifierFlags) -> String? {
fileprivate func vimModifierFlags(_ modifierFlags: NSEventModifierFlags) -> String? {
var result = ""
let control = modifierFlags.contains(.ControlKeyMask)
let option = modifierFlags.contains(.AlternateKeyMask)
let command = modifierFlags.contains(.CommandKeyMask)
let control = modifierFlags.contains(.control)
let option = modifierFlags.contains(.option)
let command = modifierFlags.contains(.command)
if control {
result += "C-"
@ -835,7 +830,7 @@ extension NeoVimView: NSTextInputClient {
// MARK: - Gesture Events
extension NeoVimView {
override public func magnifyWithEvent(event: NSEvent) {
override open func magnify(with event: NSEvent) {
let factor = 1 + event.magnification
let pinchTargetScale = self.pinchTargetScale * factor
let resultingFontSize = round(pinchTargetScale * self._font.pointSize)
@ -844,18 +839,18 @@ extension NeoVimView {
}
switch event.phase {
case NSEventPhase.Began:
let pinchImageRep = self.bitmapImageRepForCachingDisplayInRect(self.bounds)!
self.cacheDisplayInRect(self.bounds, toBitmapImageRep: pinchImageRep)
case NSEventPhase.began:
let pinchImageRep = self.bitmapImageRepForCachingDisplay(in: self.bounds)!
self.cacheDisplay(in: self.bounds, to: pinchImageRep)
self.pinchImage = NSImage()
self.pinchImage.addRepresentation(pinchImageRep)
self.isCurrentlyPinching = true
self.needsDisplay = true
case NSEventPhase.Ended, NSEventPhase.Cancelled:
case NSEventPhase.ended, NSEventPhase.cancelled:
self.isCurrentlyPinching = false
self.font = self.fontManager.convertFont(self._font, toSize: resultingFontSize)
self.font = self.fontManager.convert(self._font, toSize: resultingFontSize)
self.pinchTargetScale = 1
default:
@ -867,19 +862,19 @@ extension NeoVimView {
// MARK: - Mouse Events
extension NeoVimView {
override public func mouseDown(event: NSEvent) {
override open func mouseDown(with event: NSEvent) {
self.mouse(event: event, vimName:"LeftMouse")
}
override public func mouseUp(event: NSEvent) {
override open func mouseUp(with event: NSEvent) {
self.mouse(event: event, vimName:"LeftRelease")
}
override public func mouseDragged(event: NSEvent) {
override open func mouseDragged(with event: NSEvent) {
self.mouse(event: event, vimName:"LeftDrag")
}
override public func scrollWheel(event: NSEvent) {
override open func scrollWheel(with event: NSEvent) {
let (deltaX, deltaY) = (event.scrollingDeltaX, event.scrollingDeltaY)
if deltaX == 0 && deltaY == 0 {
return
@ -908,8 +903,8 @@ extension NeoVimView {
}
}
private func cellPositionFor(event event: NSEvent) -> Position {
let location = self.convertPoint(event.locationInWindow, fromView: nil)
fileprivate func cellPositionFor(event: NSEvent) -> Position {
let location = self.convert(event.locationInWindow, from: nil)
let row = Int((location.x - self.xOffset) / self.cellSize.width)
let column = Int((self.bounds.size.height - location.y - self.yOffset) / self.cellSize.height)
@ -918,7 +913,7 @@ extension NeoVimView {
return cellPosition
}
private func mouse(event event: NSEvent, vimName: String) {
fileprivate func mouse(event: NSEvent, vimName: String) {
let cellPosition = self.cellPositionFor(event: event)
guard self.shouldFireVimInputFor(event: event, newCellPosition: cellPosition) else {
return
@ -938,9 +933,9 @@ extension NeoVimView {
self.agent.vimInput(result)
}
private func shouldFireVimInputFor(event event:NSEvent, newCellPosition: Position) -> Bool {
fileprivate func shouldFireVimInputFor(event:NSEvent, newCellPosition: Position) -> Bool {
let type = event.type
guard type == .LeftMouseDragged || type == .RightMouseDragged || type == .OtherMouseDragged else {
guard type == .leftMouseDragged || type == .rightMouseDragged || type == .otherMouseDragged else {
self.lastClickedCellPosition = newCellPosition
return true
}
@ -953,7 +948,7 @@ extension NeoVimView {
return true
}
private func vimClickCountFrom(event event: NSEvent) -> String {
fileprivate func vimClickCountFrom(event: NSEvent) -> String {
let clickCount = event.clickCount
guard 2 <= clickCount && clickCount <= 4 else {
@ -961,14 +956,14 @@ extension NeoVimView {
}
switch event.type {
case .LeftMouseDown, .LeftMouseUp, .RightMouseDown, .RightMouseUp:
case .leftMouseDown, .leftMouseUp, .rightMouseDown, .rightMouseUp:
return "\(clickCount)-"
default:
return ""
}
}
private func vimScrollEventNamesFor(deltaX deltaX: CGFloat, deltaY: CGFloat) -> (String, String) {
fileprivate func vimScrollEventNamesFor(deltaX: CGFloat, deltaY: CGFloat) -> (String, String) {
let typeY: String
if deltaY > 0 {
typeY = "ScrollWheelUp"
@ -986,7 +981,7 @@ extension NeoVimView {
return (typeX, typeY)
}
private func vimScrollInputFor(deltaX deltaX: CGFloat, deltaY: CGFloat,
fileprivate func vimScrollInputFor(deltaX: CGFloat, deltaY: CGFloat,
modifierFlags: NSEventModifierFlags,
cellPosition: Position) -> (String, String)
{
@ -1006,7 +1001,7 @@ extension NeoVimView {
return (resultX, resultY)
}
private func throttleScrollX(absDelta absDeltaX: CGFloat, vimInput: String) {
fileprivate func throttleScrollX(absDelta absDeltaX: CGFloat, vimInput: String) {
if absDeltaX == 0 {
self.scrollGuardCounterX = self.scrollGuardYield - 1
} else if absDeltaX <= 2 {
@ -1022,7 +1017,7 @@ extension NeoVimView {
}
}
private func throttleScrollY(absDelta absDeltaY: CGFloat, vimInput: String) {
fileprivate func throttleScrollY(absDelta absDeltaY: CGFloat, vimInput: String) {
if absDeltaY == 0 {
self.scrollGuardCounterY = self.scrollGuardYield - 1
} else if absDeltaY <= 2 {
@ -1042,7 +1037,7 @@ extension NeoVimView {
// MARK: - NeoVimUiBridgeProtocol
extension NeoVimView: NeoVimUiBridgeProtocol {
public func resizeToWidth(width: Int32, height: Int32) {
public func resize(toWidth width: Int32, height: Int32) {
DispatchUtils.gui {
// NSLog("\(#function): \(width):\(height)")
self.grid.resize(Size(width: Int(width), height: Int(height)))
@ -1067,11 +1062,11 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
height: self.cellSize.height
)
let rect = CGRect(origin: origin, size: size)
self.setNeedsDisplayInRect(rect)
self.setNeedsDisplay(rect)
}
}
public func gotoPosition(position: Position, screenCursor: Position) {
public func gotoPosition(_ position: Position, screenCursor: Position) {
DispatchUtils.gui {
// NSLog("\(#function): \(position), \(screenCursor)")
@ -1118,12 +1113,12 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
public func mouseOff() {
}
public func modeChange(mode: Mode) {
public func modeChange(_ mode: Mode) {
// NSLog("mode changed to: %02x", mode.rawValue)
self.mode = mode
}
public func setScrollRegionToTop(top: Int32, bottom: Int32, left: Int32, right: Int32) {
public func setScrollRegionToTop(_ top: Int32, bottom: Int32, left: Int32, right: Int32) {
DispatchUtils.gui {
let region = Region(top: Int(top), bottom: Int(bottom), left: Int(left), right: Int(right))
self.grid.setScrollRegion(region)
@ -1131,20 +1126,20 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
}
}
public func scroll(count: Int32) {
public func scroll(_ count: Int32) {
DispatchUtils.gui {
self.grid.scroll(Int(count))
self.setNeedsDisplay(region: self.grid.region)
}
}
public func highlightSet(attrs: CellAttributes) {
public func highlightSet(_ attrs: CellAttributes) {
DispatchUtils.gui {
self.grid.attrs = attrs
}
}
public func put(string: String, screenCursor: Position) {
public func put(_ string: String, screenCursor: Position) {
DispatchUtils.gui {
let curPos = self.grid.putPosition
// NSLog("\(#function): \(curPos) -> \(string)")
@ -1164,7 +1159,7 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
}
}
public func putMarkedText(markedText: String, screenCursor: Position) {
public func putMarkedText(_ markedText: String, screenCursor: Position) {
DispatchUtils.gui {
NSLog("\(#function): '\(markedText)' -> \(screenCursor)")
@ -1182,7 +1177,7 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
}
}
public func unmarkRow(row: Int32, column: Int32) {
public func unmarkRow(_ row: Int32, column: Int32) {
DispatchUtils.gui {
let position = Position(row: Int(row), column: Int(column))
@ -1208,7 +1203,7 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
// NSLog("\(#function)")
}
public func updateForeground(fg: Int32, dark: Bool) {
public func updateForeground(_ fg: Int32, dark: Bool) {
DispatchUtils.gui {
self.grid.dark = dark
self.grid.foreground = UInt32(bitPattern: fg)
@ -1216,16 +1211,16 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
}
}
public func updateBackground(bg: Int32, dark: Bool) {
public func updateBackground(_ bg: Int32, dark: Bool) {
DispatchUtils.gui {
self.grid.dark = dark
self.grid.background = UInt32(bitPattern: bg)
self.layer?.backgroundColor = ColorUtils.colorIgnoringAlpha(self.grid.background).CGColor
self.layer?.backgroundColor = ColorUtils.colorIgnoringAlpha(self.grid.background).cgColor
// NSLog("\(ColorUtils.colorIgnoringAlpha(UInt32(bg)))")
}
}
public func updateSpecial(sp: Int32, dark: Bool) {
public func updateSpecial(_ sp: Int32, dark: Bool) {
DispatchUtils.gui {
self.grid.dark = dark
self.grid.special = UInt32(bitPattern: sp)
@ -1235,16 +1230,16 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
public func suspend() {
}
public func setTitle(title: String) {
public func setTitle(_ title: String) {
DispatchUtils.gui {
self.delegate?.setTitle(title)
}
}
public func setIcon(icon: String) {
public func setIcon(_ icon: String) {
}
public func setDirtyStatus(dirty: Bool) {
public func setDirtyStatus(_ dirty: Bool) {
DispatchUtils.gui {
self.delegate?.setDirtyStatus(dirty)
}
@ -1263,7 +1258,7 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
}
}
private func updateCursorWhenPutting(currentPosition curPos: Position, screenCursor: Position) {
fileprivate func updateCursorWhenPutting(currentPosition curPos: Position, screenCursor: Position) {
if self.mode == .Cmdline {
// When the cursor is in the command line, then we need this...
self.setNeedsDisplay(cellPosition: self.grid.previousCellPosition(curPos))
@ -1276,11 +1271,11 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
self.grid.moveCursor(screenCursor)
}
private func setNeedsDisplay(region region: Region) {
self.setNeedsDisplayInRect(self.regionRectFor(region: region))
fileprivate func setNeedsDisplay(region: Region) {
self.setNeedsDisplay(self.regionRectFor(region: region))
}
private func setNeedsDisplay(cellPosition position: Position) {
fileprivate func setNeedsDisplay(cellPosition position: Position) {
self.setNeedsDisplay(position: position)
if self.grid.isCellEmpty(position) {
@ -1292,16 +1287,16 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
}
}
private func setNeedsDisplay(position position: Position) {
fileprivate func setNeedsDisplay(position: Position) {
self.setNeedsDisplay(row: position.row, column: position.column)
}
private func setNeedsDisplay(row row: Int, column: Int) {
fileprivate func setNeedsDisplay(row: Int, column: Int) {
// Swift.print("\(#function): \(row):\(column)")
self.setNeedsDisplayInRect(self.cellRectFor(row: row, column: column))
self.setNeedsDisplay(self.cellRectFor(row: row, column: column))
}
private func setNeedsDisplay(screenCursor position: Position) {
fileprivate func setNeedsDisplay(screenCursor position: Position) {
self.setNeedsDisplay(position: position)
if self.grid.isNextCellEmpty(position) {
self.setNeedsDisplay(position: self.grid.nextCellPosition(position))

View File

@ -8,8 +8,8 @@ import Cocoa
// See http://stackoverflow.com/a/24104371 for class
public protocol NeoVimViewDelegate: class {
func setTitle(title: String)
func setDirtyStatus(dirty: Bool)
func setTitle(_ title: String)
func setDirtyStatus(_ dirty: Bool)
func cwdChanged()
func neoVimStopped()
}

View File

@ -11,38 +11,38 @@ class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var window: NSWindow!
private var workspace: Workspace = Workspace(mainView: NSView())
fileprivate var workspace: Workspace = Workspace(mainView: NSView())
@IBAction func toggleBars(sender: AnyObject!) {
@IBAction func toggleBars(_ sender: AnyObject!) {
workspace.toggleAllTools()
}
@IBAction func toggleButtons(sender: AnyObject!) {
@IBAction func toggleButtons(_ sender: AnyObject!) {
workspace.toggleToolButtons()
}
func applicationDidFinishLaunching(aNotification: NSNotification) {
func applicationDidFinishLaunching(_ aNotification: Notification) {
let contentView = self.window.contentView!
let workspace = Workspace(mainView: self.view(NSColor.yellowColor()))
let workspace = Workspace(mainView: self.view(NSColor.yellow))
self.workspace = workspace
contentView.addSubview(workspace)
workspace.autoPinEdgesToSuperviewEdges()
workspace.append(tool: WorkspaceTool(title: "Top-1", view: self.view(NSColor.whiteColor())), location: .top)
workspace.append(tool: WorkspaceTool(title: "Right-1", view: self.view(NSColor.whiteColor())), location: .right)
workspace.append(tool: WorkspaceTool(title: "Right-2", view: self.view(NSColor.greenColor())), location: .right)
workspace.append(tool: WorkspaceTool(title: "Left-1", view: self.view(NSColor.whiteColor())), location: .left)
workspace.append(tool: WorkspaceTool(title: "Left-2", view: self.view(NSColor.greenColor())), location: .left)
workspace.append(tool: WorkspaceTool(title: "Left-3", view: self.view(NSColor.magentaColor())), location: .left)
workspace.append(tool: WorkspaceTool(title: "Bottom-1", view: self.view(NSColor.whiteColor())), location: .bottom)
workspace.append(tool: WorkspaceTool(title: "Bottom-2", view: self.view(NSColor.greenColor())), location: .bottom)
workspace.append(tool: WorkspaceTool(title: "Top-1", view: self.view(NSColor.white)), location: .top)
workspace.append(tool: WorkspaceTool(title: "Right-1", view: self.view(NSColor.white)), location: .right)
workspace.append(tool: WorkspaceTool(title: "Right-2", view: self.view(NSColor.green)), location: .right)
workspace.append(tool: WorkspaceTool(title: "Left-1", view: self.view(NSColor.white)), location: .left)
workspace.append(tool: WorkspaceTool(title: "Left-2", view: self.view(NSColor.green)), location: .left)
workspace.append(tool: WorkspaceTool(title: "Left-3", view: self.view(NSColor.magenta)), location: .left)
workspace.append(tool: WorkspaceTool(title: "Bottom-1", view: self.view(NSColor.white)), location: .bottom)
workspace.append(tool: WorkspaceTool(title: "Bottom-2", view: self.view(NSColor.green)), location: .bottom)
}
private func view(color: NSColor) -> NSView {
fileprivate func view(_ color: NSColor) -> NSView {
let view = NSView(forAutoLayout: ())
view.wantsLayer = true
view.layer?.backgroundColor = color.CGColor
view.layer?.backgroundColor = color.cgColor
return view
}
}

View File

@ -819,18 +819,20 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0730;
LastUpgradeCheck = 0730;
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = "Tae Won Ha";
TargetAttributes = {
4B2A2BF61D0351810074CE9A = {
CreatedOnToolsVersion = 7.3.1;
DevelopmentTeam = H96Q2NKTQH;
LastSwiftMigration = 0800;
};
4B56F28F1D29903F00C1F92E = {
CreatedOnToolsVersion = 7.3.1;
};
4B64239E1D8EFE7500FC78C8 = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 0800;
};
4B854A191D31447C00E08DE1 = {
CreatedOnToolsVersion = 7.3.1;
@ -838,9 +840,11 @@
4BEBA5041CFF374B00673FDF = {
CreatedOnToolsVersion = 7.3.1;
DevelopmentTeam = H96Q2NKTQH;
LastSwiftMigration = 0800;
};
4BEBA5131CFF374B00673FDF = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 0800;
};
};
};
@ -1143,6 +1147,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
@ -1166,6 +1171,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.qvacua.VimR.SwiftNeoVim;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
};
name = Release;
};
@ -1212,6 +1218,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.qvacua.VimR-Workspace-Demo";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
@ -1228,6 +1235,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.qvacua.VimR-Workspace-Demo";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};
@ -1295,8 +1303,10 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
@ -1342,8 +1352,10 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
@ -1370,10 +1382,10 @@
4BEBA51E1CFF374B00673FDF /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/Mac",
@ -1383,16 +1395,17 @@
PRODUCT_BUNDLE_IDENTIFIER = com.qvacua.VimR;
PRODUCT_NAME = VimR;
SWIFT_OBJC_BRIDGING_HEADER = VimR/Bridge.h;
SWIFT_VERSION = 3.0;
};
name = Debug;
};
4BEBA51F1CFF374B00673FDF /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/Mac",
@ -1402,6 +1415,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.qvacua.VimR;
PRODUCT_NAME = VimR;
SWIFT_OBJC_BRIDGING_HEADER = VimR/Bridge.h;
SWIFT_VERSION = 3.0;
};
name = Release;
};
@ -1417,6 +1431,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.qvacua.VimRTests;
PRODUCT_NAME = VimRTests;
SWIFT_VERSION = 3.0;
};
name = Debug;
};
@ -1432,6 +1447,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.qvacua.VimRTests;
PRODUCT_NAME = VimRTests;
SWIFT_VERSION = 3.0;
};
name = Release;
};

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -25,9 +25,9 @@ class AdvancedPrefPane: PrefPane {
return true
}
private var data: AdvancedPrefData
fileprivate var data: AdvancedPrefData
private let useInteractiveZshCheckbox = NSButton(forAutoLayout: ())
fileprivate let useInteractiveZshCheckbox = NSButton(forAutoLayout: ())
init(source: Observable<Any>, initialData: AdvancedPrefData) {
self.data = initialData
@ -59,20 +59,20 @@ class AdvancedPrefPane: PrefPane {
self.addSubview(useInteractiveZsh)
self.addSubview(useInteractiveZshInfo)
paneTitle.autoPinEdgeToSuperviewEdge(.Top, withInset: 18)
paneTitle.autoPinEdgeToSuperviewEdge(.Left, withInset: 18)
paneTitle.autoPinEdgeToSuperviewEdge(.Right, withInset: 18, relation: .GreaterThanOrEqual)
paneTitle.autoPinEdge(toSuperviewEdge: .top, withInset: 18)
paneTitle.autoPinEdge(toSuperviewEdge: .left, withInset: 18)
paneTitle.autoPinEdge(toSuperviewEdge: .right, withInset: 18, relation: .greaterThanOrEqual)
useInteractiveZsh.autoPinEdge(.Top, toEdge: .Bottom, ofView: paneTitle, withOffset: 18)
useInteractiveZsh.autoPinEdgeToSuperviewEdge(.Left, withInset: 18)
useInteractiveZsh.autoPinEdge(.top, to: .bottom, of: paneTitle, withOffset: 18)
useInteractiveZsh.autoPinEdge(toSuperviewEdge: .left, withInset: 18)
useInteractiveZshInfo.autoPinEdge(.Top, toEdge: .Bottom, ofView: useInteractiveZsh, withOffset: 5)
useInteractiveZshInfo.autoPinEdgeToSuperviewEdge(.Left, withInset: 18)
useInteractiveZshInfo.autoPinEdge(.top, to: .bottom, of: useInteractiveZsh, withOffset: 5)
useInteractiveZshInfo.autoPinEdge(toSuperviewEdge: .left, withInset: 18)
useInteractiveZsh.boolState = self.data.useInteractiveZsh
}
override func subscription(source source: Observable<Any>) -> Disposable {
override func subscription(source: Observable<Any>) -> Disposable {
return source
.filter { $0 is PrefData }
.map { ($0 as! PrefData).advanced }
@ -83,12 +83,12 @@ class AdvancedPrefPane: PrefPane {
}
}
private func set(data data: AdvancedPrefData) {
fileprivate func set(data: AdvancedPrefData) {
self.data = data
self.publish(event: data)
}
private func updateViews(newData newData: AdvancedPrefData) {
fileprivate func updateViews(newData: AdvancedPrefData) {
self.useInteractiveZshCheckbox.boolState = newData.useInteractiveZsh
}
}
@ -96,7 +96,7 @@ class AdvancedPrefPane: PrefPane {
// MARK: - Actions
extension AdvancedPrefPane {
func useInteractiveZshAction(sender: NSButton) {
func useInteractiveZshAction(_ sender: NSButton) {
self.set(data: AdvancedPrefData(useInteractiveZsh: self.useInteractiveZshCheckbox.boolState))
}
}

View File

@ -23,24 +23,24 @@ class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet var debugMenu: NSMenuItem!
private let disposeBag = DisposeBag()
fileprivate let disposeBag = DisposeBag()
private let changeSubject = PublishSubject<Any>()
private let changeSink: Observable<Any>
fileprivate let changeSubject = PublishSubject<Any>()
fileprivate let changeSink: Observable<Any>
private let actionSubject = PublishSubject<Any>()
private let actionSink: Observable<Any>
fileprivate let actionSubject = PublishSubject<Any>()
fileprivate let actionSink: Observable<Any>
private let prefStore: PrefStore
fileprivate let prefStore: PrefStore
private let mainWindowManager: MainWindowManager
private let openQuicklyWindowManager: OpenQuicklyWindowManager
private let prefWindowComponent: PrefWindowComponent
fileprivate let mainWindowManager: MainWindowManager
fileprivate let openQuicklyWindowManager: OpenQuicklyWindowManager
fileprivate let prefWindowComponent: PrefWindowComponent
private let fileItemService = FileItemService()
fileprivate let fileItemService = FileItemService()
private var quitWhenAllWindowsAreClosed = false
private var launching = true
fileprivate var quitWhenAllWindowsAreClosed = false
fileprivate var launching = true
override init() {
self.actionSink = self.actionSubject.asObservable()
@ -103,17 +103,17 @@ class AppDelegate: NSObject, NSApplicationDelegate {
// MARK: - NSApplicationDelegate
extension AppDelegate {
func applicationWillFinishLaunching(_: NSNotification) {
func applicationWillFinishLaunching(_: Notification) {
self.launching = true
let appleEventManager = NSAppleEventManager.sharedAppleEventManager()
let appleEventManager = NSAppleEventManager.shared()
appleEventManager.setEventHandler(self,
andSelector: #selector(AppDelegate.handleGetUrlEvent(_:withReplyEvent:)),
forEventClass: UInt32(kInternetEventClass),
andEventID: UInt32(kAEGetURL))
}
func applicationDidFinishLaunching(_: NSNotification) {
func applicationDidFinishLaunching(_: Notification) {
// let testView = InputTestView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
// self.window.contentView?.addSubview(testView)
// self.window.makeFirstResponder(testView)
@ -121,11 +121,11 @@ extension AppDelegate {
self.launching = false
#if DEBUG
self.debugMenu.hidden = false
self.debugMenu.isHidden = false
#endif
}
func applicationOpenUntitledFile(sender: NSApplication) -> Bool {
func applicationOpenUntitledFile(_ sender: NSApplication) -> Bool {
if self.launching {
if self.prefStore.data.general.openNewWindowWhenLaunching {
self.newDocument(self)
@ -141,50 +141,50 @@ extension AppDelegate {
return false
}
func applicationShouldTerminate(sender: NSApplication) -> NSApplicationTerminateReply {
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplicationTerminateReply {
if self.mainWindowManager.hasDirtyWindows() {
let alert = NSAlert()
alert.addButtonWithTitle("Cancel")
alert.addButtonWithTitle("Discard and Quit")
alert.addButton(withTitle: "Cancel")
alert.addButton(withTitle: "Discard and Quit")
alert.messageText = "There are windows with unsaved buffers!"
alert.alertStyle = .WarningAlertStyle
alert.alertStyle = .warning
if alert.runModal() == NSAlertSecondButtonReturn {
self.quitWhenAllWindowsAreClosed = true
self.mainWindowManager.closeAllWindowsWithoutSaving()
}
return .TerminateCancel
return .terminateCancel
}
if self.mainWindowManager.hasMainWindow() {
self.quitWhenAllWindowsAreClosed = true
self.mainWindowManager.closeAllWindows()
return .TerminateCancel
return .terminateCancel
}
// There are no open main window, then just quit.
return .TerminateNow
return .terminateNow
}
// For drag & dropping files on the App icon.
func application(sender: NSApplication, openFiles filenames: [String]) {
let urls = filenames.map { NSURL(fileURLWithPath: $0) }
func application(_ sender: NSApplication, openFiles filenames: [String]) {
let urls = filenames.map { URL(fileURLWithPath: $0) }
self.mainWindowManager.newMainWindow(urls: urls)
sender.replyToOpenOrPrint(.Success)
sender.reply(toOpenOrPrint: .success)
}
}
// MARK: - AppleScript
extension AppDelegate {
func handleGetUrlEvent(event: NSAppleEventDescriptor, withReplyEvent: NSAppleEventDescriptor) {
guard let urlString = event.paramDescriptorForKeyword(UInt32(keyDirectObject))?.stringValue else {
func handleGetUrlEvent(_ event: NSAppleEventDescriptor, withReplyEvent: NSAppleEventDescriptor) {
guard let urlString = event.paramDescriptor(forKeyword: UInt32(keyDirectObject))?.stringValue else {
return
}
guard let url = NSURL(string: urlString) else {
guard let url = URL(string: urlString) else {
return
}
@ -200,16 +200,16 @@ extension AppDelegate {
return
}
let queryParams = url.query?.componentsSeparatedByString("&")
let queryParams = url.query?.components(separatedBy: "&")
let urls = queryParams?
.filter { $0.hasPrefix(filePrefix) }
.flatMap { $0.without(prefix: filePrefix).stringByRemovingPercentEncoding }
.map { NSURL(fileURLWithPath: $0) } ?? []
.flatMap { $0.without(prefix: filePrefix).removingPercentEncoding }
.map { URL(fileURLWithPath: $0) } ?? []
let cwd = queryParams?
.filter { $0.hasPrefix(cwdPrefix) }
.flatMap { $0.without(prefix: cwdPrefix).stringByRemovingPercentEncoding }
.map { NSURL(fileURLWithPath: $0) }
.first ?? NSURL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)
.flatMap { $0.without(prefix: cwdPrefix).removingPercentEncoding }
.map { URL(fileURLWithPath: $0) }
.first ?? URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)
switch action {
case .activate, .newWindow:
@ -228,24 +228,24 @@ extension AppDelegate {
// MARK: - IBActions
extension AppDelegate {
@IBAction func showPrefWindow(sender: AnyObject!) {
@IBAction func showPrefWindow(_ sender: AnyObject!) {
self.prefWindowComponent.show()
}
@IBAction func newDocument(sender: AnyObject!) {
@IBAction func newDocument(_ sender: AnyObject!) {
self.mainWindowManager.newMainWindow()
}
// Invoked when no main window is open.
@IBAction func openDocument(sender: AnyObject!) {
@IBAction func openDocument(_ sender: AnyObject!) {
let panel = NSOpenPanel()
panel.canChooseDirectories = true
panel.beginWithCompletionHandler { result in
panel.begin { result in
guard result == NSFileHandlingPanelOKButton else {
return
}
self.mainWindowManager.newMainWindow(urls: panel.URLs)
self.mainWindowManager.newMainWindow(urls: panel.urls)
}
}
}

View File

@ -21,26 +21,26 @@ extension NSButton {
extension NSAttributedString {
func draw(at point: CGPoint, angle: CGFloat) {
let translation = NSAffineTransform()
let rotation = NSAffineTransform()
var translation = AffineTransform.identity
var rotation = AffineTransform.identity
translation.translateXBy(point.x, yBy: point.y)
rotation.rotateByRadians(angle)
translation.translate(x: point.x, y: point.y)
rotation.rotate(byRadians: angle)
translation.concat()
rotation.concat()
(translation as NSAffineTransform).concat()
(rotation as NSAffineTransform).concat()
self.drawAtPoint(CGPoint.zero)
self.draw(at: CGPoint.zero)
rotation.invert()
translation.invert()
rotation.concat()
translation.concat()
(rotation as NSAffineTransform).concat()
(translation as NSAffineTransform).concat()
}
// From https://developer.apple.com/library/mac/qa/qa1487/_index.html
static func link(withUrl url: NSURL, text: String, font: NSFont? = nil) -> NSAttributedString {
static func link(withUrl url: URL, text: String, font: NSFont? = nil) -> NSAttributedString {
let attrString = NSMutableAttributedString(string: text)
let range = NSRange(location: 0, length: attrString.length)
@ -49,9 +49,9 @@ extension NSAttributedString {
attrString.addAttribute(NSFontAttributeName, value: font!, range: range)
}
attrString.addAttribute(NSLinkAttributeName, value: url.absoluteString, range: range)
attrString.addAttribute(NSForegroundColorAttributeName, value: NSColor.blueColor(), range: range)
attrString.addAttribute(NSForegroundColorAttributeName, value: NSColor.blue, range: range)
attrString.addAttribute(NSUnderlineStyleAttributeName,
value: NSNumber(integer: NSUnderlineStyle.StyleSingle.rawValue), range: range)
value: NSNumber(value: NSUnderlineStyle.styleSingle.rawValue as Int), range: range)
attrString.endEditing()
return attrString
@ -79,22 +79,22 @@ extension NSTableView {
let tableView = NSTableView(frame: CGRect.zero)
let column = NSTableColumn(identifier: "name")
column.editable = false
column.isEditable = false
tableView.addTableColumn(column)
tableView.rowSizeStyle = .Default
tableView.rowSizeStyle = .default
tableView.sizeLastColumnToFit()
tableView.allowsEmptySelection = false
tableView.allowsMultipleSelection = false
tableView.headerView = nil
tableView.focusRingType = .None
tableView.focusRingType = .none
return tableView
}
static func standardSourceListTableView() -> NSTableView {
let tableView = self.standardTableView()
tableView.selectionHighlightStyle = .SourceList
tableView.selectionHighlightStyle = .sourceList
return tableView
}
@ -109,7 +109,7 @@ extension NSScrollView {
scrollView.hasVerticalScroller = true
scrollView.hasHorizontalScroller = true
scrollView.autohidesScrollers = true
scrollView.borderType = .BezelBorder
scrollView.borderType = .bezelBorder
return scrollView
}

View File

@ -13,7 +13,7 @@ struct AppearancePrefData: Equatable {
}
func == (left: AppearancePrefData, right: AppearancePrefData) -> Bool {
return left.editorUsesLigatures == right.editorUsesLigatures && left.editorFont.isEqualTo(right.editorFont)
return left.editorUsesLigatures == right.editorUsesLigatures && left.editorFont.isEqual(to: right.editorFont)
}
class AppearancePrefPane: PrefPane, NSComboBoxDelegate, NSControlTextEditingDelegate {
@ -26,21 +26,21 @@ class AppearancePrefPane: PrefPane, NSComboBoxDelegate, NSControlTextEditingDele
return true
}
private var data: AppearancePrefData {
fileprivate var data: AppearancePrefData {
didSet {
self.updateViews(newData: self.data)
}
}
private let fontManager = NSFontManager.sharedFontManager()
fileprivate let fontManager = NSFontManager.shared()
private let sizes = [9, 10, 11, 12, 13, 14, 16, 18, 24, 36, 48, 64]
private let sizeCombo = NSComboBox(forAutoLayout: ())
private let fontPopup = NSPopUpButton(frame: CGRect.zero, pullsDown: false)
private let ligatureCheckbox = NSButton(forAutoLayout: ())
private let previewArea = NSTextView(frame: CGRect.zero)
fileprivate let sizes = [9, 10, 11, 12, 13, 14, 16, 18, 24, 36, 48, 64]
fileprivate let sizeCombo = NSComboBox(forAutoLayout: ())
fileprivate let fontPopup = NSPopUpButton(frame: CGRect.zero, pullsDown: false)
fileprivate let ligatureCheckbox = NSButton(forAutoLayout: ())
fileprivate let previewArea = NSTextView(frame: CGRect.zero)
private let exampleText =
fileprivate let exampleText =
"abcdefghijklmnopqrstuvwxyz\n" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ\n" +
"0123456789\n" +
@ -59,12 +59,12 @@ class AppearancePrefPane: PrefPane, NSComboBoxDelegate, NSControlTextEditingDele
fatalError("init(coder:) has not been implemented")
}
private func set(data data: AppearancePrefData) {
fileprivate func set(data: AppearancePrefData) {
self.data = data
self.publish(event: data)
}
override func subscription(source source: Observable<Any>) -> Disposable {
override func subscription(source: Observable<Any>) -> Disposable {
return source
.filter { $0 is PrefData }
.map { ($0 as! PrefData).appearance }
@ -83,14 +83,14 @@ class AppearancePrefPane: PrefPane, NSComboBoxDelegate, NSControlTextEditingDele
fontPopup.translatesAutoresizingMaskIntoConstraints = false
fontPopup.target = self
fontPopup.action = #selector(AppearancePrefPane.fontPopupAction)
fontPopup.addItemsWithTitles(self.fontManager.availableFontNamesWithTraits(.FixedPitchFontMask)!)
fontPopup.addItems(withTitles: self.fontManager.availableFontNames(with: .fixedPitchFontMask)!)
let sizeCombo = self.sizeCombo
sizeCombo.setDelegate(self)
sizeCombo.delegate = self
sizeCombo.target = self
sizeCombo.action = #selector(AppearancePrefPane.sizeComboBoxDidEnter(_:))
self.sizes.forEach { string in
sizeCombo.addItemWithObjectValue(string)
sizeCombo.addItem(withObjectValue: string)
}
let ligatureCheckbox = self.ligatureCheckbox
@ -99,23 +99,23 @@ class AppearancePrefPane: PrefPane, NSComboBoxDelegate, NSControlTextEditingDele
action: #selector(AppearancePrefPane.usesLigaturesAction(_:)))
let previewArea = self.previewArea
previewArea.editable = true
previewArea.maxSize = CGSize(width: CGFloat.max, height: CGFloat.max)
previewArea.verticallyResizable = true
previewArea.horizontallyResizable = true
previewArea.isEditable = true
previewArea.maxSize = CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)
previewArea.isVerticallyResizable = true
previewArea.isHorizontallyResizable = true
previewArea.textContainer?.heightTracksTextView = false
previewArea.textContainer?.widthTracksTextView = false
previewArea.autoresizingMask = [ .ViewWidthSizable, .ViewHeightSizable]
previewArea.textContainer?.containerSize = CGSize.init(width: CGFloat.max, height: CGFloat.max)
previewArea.autoresizingMask = [ .viewWidthSizable, .viewHeightSizable]
previewArea.textContainer?.containerSize = CGSize.init(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)
previewArea.layoutManager?.replaceTextStorage(NSTextStorage(string: self.exampleText))
previewArea.richText = false
previewArea.isRichText = false
previewArea.turnOffLigatures(self)
let previewScrollView = NSScrollView(forAutoLayout: ())
previewScrollView.hasVerticalScroller = true
previewScrollView.hasHorizontalScroller = true
previewScrollView.autohidesScrollers = true
previewScrollView.borderType = .BezelBorder
previewScrollView.borderType = .bezelBorder
previewScrollView.documentView = previewArea
self.addSubview(paneTitle)
@ -126,31 +126,31 @@ class AppearancePrefPane: PrefPane, NSComboBoxDelegate, NSControlTextEditingDele
self.addSubview(ligatureCheckbox)
self.addSubview(previewScrollView)
paneTitle.autoPinEdgeToSuperviewEdge(.Top, withInset: 18)
paneTitle.autoPinEdgeToSuperviewEdge(.Left, withInset: 18)
paneTitle.autoPinEdge(toSuperviewEdge: .top, withInset: 18)
paneTitle.autoPinEdge(toSuperviewEdge: .left, withInset: 18)
fontTitle.autoPinEdge(.Left, toEdge: .Left, ofView: paneTitle)
fontTitle.autoAlignAxis(.Baseline, toSameAxisOfView: fontPopup)
fontTitle.autoPinEdge(.left, to: .left, of: paneTitle)
fontTitle.autoAlignAxis(.baseline, toSameAxisOf: fontPopup)
fontPopup.autoPinEdge(.Top, toEdge: .Bottom, ofView: paneTitle, withOffset: 18)
fontPopup.autoPinEdge(.Left, toEdge: .Right, ofView: fontTitle, withOffset: 5)
fontPopup.autoSetDimension(.Width, toSize: 240)
fontPopup.autoPinEdge(.top, to: .bottom, of: paneTitle, withOffset: 18)
fontPopup.autoPinEdge(.left, to: .right, of: fontTitle, withOffset: 5)
fontPopup.autoSetDimension(.width, toSize: 240)
sizeCombo.autoSetDimension(.Width, toSize: 60)
sizeCombo.autoSetDimension(.width, toSize: 60)
// If we use .Baseline the combo box is placed one pixel off...
sizeCombo.autoAlignAxis(.Horizontal, toSameAxisOfView: fontPopup)
sizeCombo.autoPinEdge(.Left, toEdge: .Right, ofView: fontPopup, withOffset: 5)
sizeCombo.autoAlignAxis(.horizontal, toSameAxisOf: fontPopup)
sizeCombo.autoPinEdge(.left, to: .right, of: fontPopup, withOffset: 5)
ligatureCheckbox.autoPinEdge(.Top, toEdge: .Bottom, ofView: sizeCombo, withOffset: 18)
ligatureCheckbox.autoPinEdge(.Left, toEdge: .Right, ofView: fontTitle, withOffset: 5)
ligatureCheckbox.autoPinEdge(.top, to: .bottom, of: sizeCombo, withOffset: 18)
ligatureCheckbox.autoPinEdge(.left, to: .right, of: fontTitle, withOffset: 5)
previewScrollView.autoSetDimension(.Height, toSize: 200, relation: .GreaterThanOrEqual)
previewScrollView.autoPinEdge(.Top, toEdge: .Bottom, ofView: ligatureCheckbox, withOffset: 18)
previewScrollView.autoPinEdgeToSuperviewEdge(.Right, withInset: 18)
previewScrollView.autoPinEdgeToSuperviewEdge(.Bottom, withInset: 18)
previewScrollView.autoPinEdgeToSuperviewEdge(.Left, withInset: 18)
previewScrollView.autoSetDimension(.height, toSize: 200, relation: .greaterThanOrEqual)
previewScrollView.autoPinEdge(.top, to: .bottom, of: ligatureCheckbox, withOffset: 18)
previewScrollView.autoPinEdge(toSuperviewEdge: .right, withInset: 18)
previewScrollView.autoPinEdge(toSuperviewEdge: .bottom, withInset: 18)
previewScrollView.autoPinEdge(toSuperviewEdge: .left, withInset: 18)
self.fontPopup.selectItemWithTitle(self.data.editorFont.fontName)
self.fontPopup.selectItem(withTitle: self.data.editorFont.fontName)
self.sizeCombo.stringValue = String(Int(self.data.editorFont.pointSize))
self.ligatureCheckbox.state = self.data.editorUsesLigatures ? NSOnState : NSOffState
self.previewArea.font = self.data.editorFont
@ -161,10 +161,10 @@ class AppearancePrefPane: PrefPane, NSComboBoxDelegate, NSControlTextEditingDele
}
}
private func updateViews(newData newData: AppearancePrefData) {
fileprivate func updateViews(newData: AppearancePrefData) {
let newFont = newData.editorFont
self.fontPopup.selectItemWithTitle(newFont.fontName)
self.fontPopup.selectItem(withTitle: newFont.fontName)
self.sizeCombo.stringValue = String(Int(newFont.pointSize))
self.ligatureCheckbox.boolState = newData.editorUsesLigatures
self.previewArea.font = newData.editorFont
@ -180,16 +180,16 @@ class AppearancePrefPane: PrefPane, NSComboBoxDelegate, NSControlTextEditingDele
// MARK: - Actions
extension AppearancePrefPane {
func usesLigaturesAction(sender: NSButton) {
func usesLigaturesAction(_ sender: NSButton) {
self.set(data: AppearancePrefData(editorFont: self.data.editorFont, editorUsesLigatures: sender.boolState))
}
func fontPopupAction(sender: NSPopUpButton) {
func fontPopupAction(_ sender: NSPopUpButton) {
guard let selectedItem = self.fontPopup.selectedItem else {
return
}
guard selectedItem != self.data.editorFont.fontName else {
guard selectedItem.title != self.data.editorFont.fontName else {
return
}
@ -200,25 +200,25 @@ extension AppearancePrefPane {
self.set(data: AppearancePrefData(editorFont: newFont, editorUsesLigatures: self.data.editorUsesLigatures))
}
func comboBoxSelectionDidChange(notification: NSNotification) {
guard notification.object! === self.sizeCombo else {
func comboBoxSelectionDidChange(_ notification: Notification) {
guard (notification.object as! NSComboBox) === self.sizeCombo else {
return
}
let newFontSize = self.cappedFontSize(Int(self.sizes[self.sizeCombo.indexOfSelectedItem]))
let newFont = self.fontManager.convertFont(self.data.editorFont, toSize: newFontSize)
let newFont = self.fontManager.convert(self.data.editorFont, toSize: newFontSize)
self.set(data: AppearancePrefData(editorFont: newFont, editorUsesLigatures: self.data.editorUsesLigatures))
}
func sizeComboBoxDidEnter(sender: AnyObject!) {
func sizeComboBoxDidEnter(_ sender: AnyObject!) {
let newFontSize = self.cappedFontSize(self.sizeCombo.integerValue)
let newFont = self.fontManager.convertFont(self.data.editorFont, toSize: newFontSize)
let newFont = self.fontManager.convert(self.data.editorFont, toSize: newFontSize)
self.set(data: AppearancePrefData(editorFont: newFont, editorUsesLigatures: self.data.editorUsesLigatures))
}
private func cappedFontSize(size: Int) -> CGFloat {
fileprivate func cappedFontSize(_ size: Int) -> CGFloat {
guard size >= 4 else {
return 13
}

View File

@ -24,7 +24,7 @@ class Application: NSApplication {
fatalError("init(coder:) has not been implemented")
}
@IBAction override func showHelp(sender: AnyObject!) {
NSWorkspace.sharedWorkspace().openURL(NSURL(string: "https://github.com/qvacua/vimr/wiki")!)
@IBAction override func showHelp(_ sender: Any!) {
NSWorkspace.shared().open(URL(string: "https://github.com/qvacua/vimr/wiki")!)
}
}

View File

@ -34,11 +34,11 @@ class StandardFlow: Flow {
self.subject.onCompleted()
}
func subscription(source source: Observable<Any>) -> Disposable {
func subscription(source: Observable<Any>) -> Disposable {
preconditionFailure("Please override")
}
func publish(event event: Any) {
func publish(event: Any) {
self.subject.onNext(event)
}
}
@ -69,11 +69,11 @@ class StandardComponent: NSObject, Component {
preconditionFailure("Please override")
}
func subscription(source source: Observable<Any>) -> Disposable {
func subscription(source: Observable<Any>) -> Disposable {
preconditionFailure("Please override")
}
func publish(event event: Any) {
func publish(event: Any) {
self.subject.onNext(event)
}
}

View File

@ -7,7 +7,7 @@ import Foundation
class FileItem : CustomStringConvertible {
let url: NSURL
let url: URL
let dir: Bool
let hidden: Bool
let package: Bool
@ -28,18 +28,18 @@ class FileItem : CustomStringConvertible {
+ "children=\(self.children.count)>"
}
init(_ url: NSURL) {
init(_ url: URL) {
self.url = url
self.dir = url.dir
self.hidden = url.hidden
self.package = url.package
}
func removeChild(withUrl url: NSURL) {
guard let idx = self.children.indexOf({ $0.url == url }) else {
func removeChild(withUrl url: URL) {
guard let idx = self.children.index(where: { $0.url == url }) else {
return
}
self.children.removeAtIndex(idx)
self.children.remove(at: idx)
}
}

View File

@ -22,7 +22,7 @@ class FileItemIgnorePattern: Hashable, CustomStringConvertible {
let folderPattern: Bool
let pattern: String
private let patternAsFileSysRep: UnsafeMutablePointer<Int8>
fileprivate let patternAsFileSysRep: UnsafeMutablePointer<Int8>
init(pattern: String) {
self.pattern = pattern
@ -31,14 +31,14 @@ class FileItemIgnorePattern: Hashable, CustomStringConvertible {
let fileSysRep = (pattern as NSString).fileSystemRepresentation
let len = Int(strlen(fileSysRep))
self.patternAsFileSysRep = UnsafeMutablePointer<Int8>.alloc(len + 1)
self.patternAsFileSysRep = UnsafeMutablePointer<Int8>.allocate(capacity: len + 1)
memcpy(self.patternAsFileSysRep, fileSysRep, len)
self.patternAsFileSysRep[len] = 0
}
deinit {
let len = Int(strlen(self.patternAsFileSysRep))
self.patternAsFileSysRep.dealloc(len + 1)
self.patternAsFileSysRep.deallocate(capacity: len + 1)
}
func match(absolutePath path: String) -> Bool {
@ -57,4 +57,4 @@ class FileItemIgnorePattern: Hashable, CustomStringConvertible {
return matches != FNM_NOMATCH
}
}
}

View File

@ -15,31 +15,31 @@ class Token: Equatable {}
class FileItemService {
private(set) var ignorePatterns: Set<FileItemIgnorePattern> = [] {
fileprivate(set) var ignorePatterns: Set<FileItemIgnorePattern> = [] {
didSet {
self.ignoreToken = Token()
}
}
/// Used to cache fnmatch calls in `FileItem`.
private var ignoreToken = Token()
fileprivate var ignoreToken = Token()
/// When at least this much of non-directory and visible files are scanned, they are emitted.
private let emitChunkSize = 1000
fileprivate let emitChunkSize = 1000
private let scanDispatchQueue = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)
private let monitorDispatchQueue = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)
fileprivate let scanDispatchQueue = DispatchQueue.global(qos: DispatchQoS.QoSClass.userInitiated)
fileprivate let monitorDispatchQueue = DispatchQueue.global(qos: DispatchQoS.QoSClass.userInitiated)
private let root = FileItem(NSURL(fileURLWithPath: "/", isDirectory: true))
fileprivate let root = FileItem(URL(fileURLWithPath: "/", isDirectory: true))
private let fileSystemEventsLatency = Double(2)
private var monitors = [NSURL: FileSystemEventMonitor]()
private var monitorCounter = [NSURL: Int]()
fileprivate let fileSystemEventsLatency = Double(2)
fileprivate var monitors = [URL: FileSystemEventMonitor]()
fileprivate var monitorCounter = [URL: Int]()
private let workspace = NSWorkspace.sharedWorkspace()
private let iconsCache = NSCache()
fileprivate let workspace = NSWorkspace.shared()
fileprivate let iconsCache = NSCache<NSURL, NSImage>()
private var spinLock = OS_SPINLOCK_INIT
fileprivate var spinLock = OS_SPINLOCK_INIT
init() {
self.iconsCache.countLimit = 2000
@ -50,22 +50,17 @@ class FileItemService {
self.ignorePatterns = patterns
}
func icon(forUrl url: NSURL) -> NSImage? {
guard let path = url.path else {
return nil
}
let icon = workspace.iconForFile(path)
func icon(forUrl url: URL) -> NSImage? {
let path = url.path
let icon = workspace.icon(forFile: path)
icon.size = CGSize(width: 16, height: 16)
self.iconsCache.setObject(icon, forKey: url)
self.iconsCache.setObject(icon, forKey: url as NSURL)
return icon
}
func monitor(url url: NSURL) {
guard let path = url.path else {
return
}
func monitor(url: URL) {
let path = url.path
// FIXME: Handle EonilFileSystemEventFlag.RootChanged, ie watchRoot: true
let monitor = FileSystemEventMonitor(pathsToWatch: [path],
@ -73,7 +68,7 @@ class FileItemService {
watchRoot: false,
queue: self.monitorDispatchQueue)
{ [unowned self] events in
let urls = events.map { NSURL(fileURLWithPath: $0.path) }
let urls = events.map { URL(fileURLWithPath: $0.path) }
let parent = FileUtils.commonParent(ofUrls: urls)
self.fileItem(forUrl: parent)?.needsScanChildren = true
}
@ -86,7 +81,7 @@ class FileItemService {
}
}
func unmonitor(url url: NSURL) {
func unmonitor(url: URL) {
guard let counter = self.monitorCounter[url] else {
return
}
@ -95,8 +90,8 @@ class FileItemService {
if newCounter > 0 {
self.monitorCounter[url] = newCounter
} else {
self.monitorCounter.removeValueForKey(url)
self.monitors.removeValueForKey(url)
self.monitorCounter.removeValue(forKey: url)
self.monitors.removeValue(forKey: url)
// TODO Remove cached items more aggressively?
let hasRelations = self.monitors.keys.reduce(false) { (result, monitoredUrl) in
@ -111,12 +106,12 @@ class FileItemService {
}
}
private func parentFileItem(ofUrl url: NSURL) -> FileItem {
return self.fileItem(forPathComponents: Array(url.pathComponents!.dropLast()))!
fileprivate func parentFileItem(ofUrl url: URL) -> FileItem {
return self.fileItem(forPathComponents: Array(url.pathComponents.dropLast()))!
}
func flatFileItems(ofUrl url: NSURL) -> Observable<[FileItem]> {
guard url.fileURL else {
func flatFileItems(ofUrl url: URL) -> Observable<[FileItem]> {
guard url.isFileURL else {
return Observable.empty()
}
@ -124,16 +119,13 @@ class FileItemService {
return Observable.empty()
}
guard let pathComponents = url.pathComponents else {
return Observable.empty()
}
let pathComponents = url.pathComponents
return Observable.create { [unowned self] observer in
let cancel = AnonymousDisposable {
// noop
}
dispatch_async(self.scanDispatchQueue) { [unowned self] in
self.scanDispatchQueue.async { [unowned self] in
guard let targetItem = self.fileItem(forPathComponents: pathComponents) else {
observer.onCompleted()
return
@ -166,7 +158,7 @@ class FileItemService {
item.ignoreToken = self.ignoreToken
item.ignore = false
let path = item.url.path!
let path = item.url.path
for pattern in self.ignorePatterns {
// We don't use `String.FnMatchOption.leadingDir` (`FNM_LEADING_DIR`) for directories since we do not
// scan ignored directories at all when filtering. For example "*/.git" would create a `FileItem`
@ -197,11 +189,8 @@ class FileItemService {
}
}
private func fileItem(forUrl url: NSURL) -> FileItem? {
guard let pathComponents = url.pathComponents else {
return nil
}
fileprivate func fileItem(forUrl url: URL) -> FileItem? {
let pathComponents = url.pathComponents
return self.fileItem(forPathComponents: pathComponents)
}
@ -209,7 +198,7 @@ class FileItemService {
/// instantiates the intermediate `FileItem`s.
///
/// - returns: `FileItem` corresponding to `pathComponents`. `nil` if the file does not exist.
private func fileItem(forPathComponents pathComponents: [String]) -> FileItem? {
fileprivate func fileItem(forPathComponents pathComponents: [String]) -> FileItem? {
let result = pathComponents.dropFirst().reduce(self.root) { (resultItem, childName) -> FileItem? in
guard let parent = resultItem else {
return nil
@ -230,11 +219,11 @@ class FileItemService {
/// - parent: parent of the child.
/// - create: whether to create the child `FileItem` if it's not scanned yet.
/// - returns: child `FileItem` or nil.
private func child(withName name: String, ofParent parent: FileItem, create: Bool = false) -> FileItem? {
fileprivate func child(withName name: String, ofParent parent: FileItem, create: Bool = false) -> FileItem? {
let filteredChildren = parent.children.filter { $0.url.lastPathComponent == name }
if filteredChildren.isEmpty && create {
let childUrl = parent.url.URLByAppendingPathComponent(name)
let childUrl = parent.url.appendingPathComponent(name)
guard FileUtils.fileExistsAtUrl(childUrl) else {
return nil
@ -249,7 +238,7 @@ class FileItemService {
return filteredChildren.first
}
private func scanChildren(item: FileItem) {
fileprivate func scanChildren(_ item: FileItem) {
let children = FileUtils.directDescendants(item.url).map(FileItem.init)
self.syncAddChildren { item.children = children }
@ -257,7 +246,7 @@ class FileItemService {
item.needsScanChildren = false
}
private func syncAddChildren(@noescape fn: () -> Void) {
fileprivate func syncAddChildren(_ fn: () -> Void) {
OSSpinLockLock(&self.spinLock)
fn()
OSSpinLockUnlock(&self.spinLock)

View File

@ -7,23 +7,23 @@ import Foundation
class FileUtils {
private static let keysToGet = [
NSURLIsDirectoryKey,
NSURLIsHiddenKey,
NSURLIsAliasFileKey,
NSURLIsSymbolicLinkKey
fileprivate static let keysToGet = [
URLResourceKey.isDirectoryKey,
URLResourceKey.isHiddenKey,
URLResourceKey.isAliasFileKey,
URLResourceKey.isSymbolicLinkKey
]
private static let scanOptions: NSDirectoryEnumerationOptions = [
NSDirectoryEnumerationOptions.SkipsSubdirectoryDescendants,
NSDirectoryEnumerationOptions.SkipsPackageDescendants
fileprivate static let scanOptions: FileManager.DirectoryEnumerationOptions = [
FileManager.DirectoryEnumerationOptions.skipsSubdirectoryDescendants,
FileManager.DirectoryEnumerationOptions.skipsPackageDescendants
]
private static let fileManager = NSFileManager.defaultManager()
fileprivate static let fileManager = FileManager.default
static func directDescendants(url: NSURL) -> [NSURL] {
guard let childUrls = try? self.fileManager.contentsOfDirectoryAtURL(
url, includingPropertiesForKeys: self.keysToGet, options: self.scanOptions
static func directDescendants(_ url: URL) -> [URL] {
guard let childUrls = try? self.fileManager.contentsOfDirectory(
at: url, includingPropertiesForKeys: self.keysToGet, options: self.scanOptions
) else {
// FIXME error handling
return []
@ -32,33 +32,30 @@ class FileUtils {
return childUrls
}
static func fileExistsAtUrl(url: NSURL) -> Bool {
guard url.fileURL else {
static func fileExistsAtUrl(_ url: URL) -> Bool {
guard url.isFileURL else {
return false
}
guard let path = url.path else {
return false
}
return self.fileManager.fileExistsAtPath(path)
let path = url.path
return self.fileManager.fileExists(atPath: path)
}
static func commonParent(ofUrls urls: [NSURL]) -> NSURL {
static func commonParent(ofUrls urls: [URL]) -> URL {
guard urls.count > 0 else {
return NSURL(fileURLWithPath: "/", isDirectory: true)
return URL(fileURLWithPath: "/", isDirectory: true)
}
let pathComps = urls.map { $0.pathComponents! }
let pathComps = urls.map { $0.pathComponents }
let min = pathComps.reduce(pathComps[0].count) { (result, comps) in result < comps.count ? result : comps.count }
let pathCompsWithMinCount = pathComps.filter { $0.count == min }
let possibleParent = NSURL.fileURLWithPathComponents(pathCompsWithMinCount[0])!
let possibleParent = NSURL.fileURL(withPathComponents: pathCompsWithMinCount[0])!
let minPathComponents = Set(pathComps.map { $0[min - 1] })
if minPathComponents.count == 1 {
return possibleParent.dir ? possibleParent : possibleParent.URLByDeletingLastPathComponent!
return possibleParent.dir ? possibleParent : possibleParent.deletingLastPathComponent()
}
return possibleParent.URLByDeletingLastPathComponent!
return possibleParent.deletingLastPathComponent()
}
}

View File

@ -5,15 +5,15 @@
import Foundation
extension NSURL {
extension URL {
func parent(ofUrl url: NSURL) -> Bool {
guard self.fileURL && url.fileURL else {
func parent(ofUrl url: URL) -> Bool {
guard self.isFileURL && url.isFileURL else {
return false
}
let myPathComps = self.pathComponents!
let targetPathComps = url.pathComponents!
let myPathComps = self.pathComponents
let targetPathComps = url.pathComponents
guard targetPathComps.count > myPathComps.count else {
return false
@ -29,11 +29,11 @@ extension NSURL {
///
/// - parameters:
/// - key: The `key`-parameter of `NSURL.getResourceValue`.
func resourceValue(key: String) -> Bool {
func resourceValue(_ key: String) -> Bool {
var rsrc: AnyObject?
do {
try self.getResourceValue(&rsrc, forKey: key)
try (self as NSURL).getResourceValue(&rsrc, forKey: URLResourceKey(rawValue: key))
} catch {
// FIXME error handling
print("\(#function): \(self) -> ERROR while getting \(key)")
@ -48,14 +48,14 @@ extension NSURL {
}
var dir: Bool {
return self.resourceValue(NSURLIsDirectoryKey)
return self.resourceValue(URLResourceKey.isDirectoryKey.rawValue)
}
var hidden: Bool {
return self.resourceValue(NSURLIsHiddenKey)
return self.resourceValue(URLResourceKey.isHiddenKey.rawValue)
}
var package: Bool {
return self.resourceValue(NSURLIsPackageKey)
return self.resourceValue(URLResourceKey.isPackageKey.rawValue)
}
}

View File

@ -30,11 +30,11 @@ class GeneralPrefPane: PrefPane, NSTextFieldDelegate {
return true
}
private var data: GeneralPrefData
fileprivate var data: GeneralPrefData
private let openWhenLaunchingCheckbox = NSButton(forAutoLayout: ())
private let openOnReactivationCheckbox = NSButton(forAutoLayout: ())
private let ignoreField = NSTextField(forAutoLayout: ())
fileprivate let openWhenLaunchingCheckbox = NSButton(forAutoLayout: ())
fileprivate let openOnReactivationCheckbox = NSButton(forAutoLayout: ())
fileprivate let ignoreField = NSTextField(forAutoLayout: ())
init(source: Observable<Any>, initialData: GeneralPrefData) {
self.data = initialData
@ -63,8 +63,8 @@ class GeneralPrefPane: PrefPane, NSTextFieldDelegate {
let ignoreListTitle = self.titleTextField(title: "Files To Ignore:")
let ignoreField = self.ignoreField
NSNotificationCenter.defaultCenter()
.addObserverForName(NSControlTextDidEndEditingNotification, object: ignoreField, queue: nil) { [unowned self] _ in
NotificationCenter.default
.addObserver(forName: NSNotification.Name.NSControlTextDidEndEditing, object: ignoreField, queue: nil) { [unowned self] _ in
self.ignorePatternsAction()
}
let ignoreInfo = self.infoTextField(text: "")
@ -73,9 +73,9 @@ class GeneralPrefPane: PrefPane, NSTextFieldDelegate {
let cliToolTitle = self.titleTextField(title: "CLI Tool:")
let cliToolButton = NSButton(forAutoLayout: ())
cliToolButton.title = "Copy 'vimr' CLI Tool..."
cliToolButton.bezelStyle = .RoundedBezelStyle
cliToolButton.bordered = true
cliToolButton.setButtonType(.MomentaryPushInButton)
cliToolButton.bezelStyle = .rounded
cliToolButton.isBordered = true
cliToolButton.setButtonType(.momentaryPushIn)
cliToolButton.target = self
cliToolButton.action = #selector(GeneralPrefPane.copyCliTool(_:))
let cliToolInfo = self.infoTextField(
@ -95,50 +95,50 @@ class GeneralPrefPane: PrefPane, NSTextFieldDelegate {
self.addSubview(cliToolButton)
self.addSubview(cliToolInfo)
paneTitle.autoPinEdgeToSuperviewEdge(.Top, withInset: 18)
paneTitle.autoPinEdgeToSuperviewEdge(.Left, withInset: 18)
paneTitle.autoPinEdgeToSuperviewEdge(.Right, withInset: 18, relation: .GreaterThanOrEqual)
paneTitle.autoPinEdge(toSuperviewEdge: .top, withInset: 18)
paneTitle.autoPinEdge(toSuperviewEdge: .left, withInset: 18)
paneTitle.autoPinEdge(toSuperviewEdge: .right, withInset: 18, relation: .greaterThanOrEqual)
openUntitledWindowTitle.autoAlignAxis(.Baseline, toSameAxisOfView: whenLaunching, withOffset: 0)
openUntitledWindowTitle.autoPinEdgeToSuperviewEdge(.Left, withInset: 18)
openUntitledWindowTitle.autoAlignAxis(.baseline, toSameAxisOf: whenLaunching, withOffset: 0)
openUntitledWindowTitle.autoPinEdge(toSuperviewEdge: .left, withInset: 18)
whenLaunching.autoPinEdge(.Top, toEdge: .Bottom, ofView: paneTitle, withOffset: 18)
whenLaunching.autoPinEdge(.Left, toEdge: .Right, ofView: openUntitledWindowTitle, withOffset: 5)
whenLaunching.autoPinEdgeToSuperviewEdge(.Right, withInset: 18, relation: .GreaterThanOrEqual)
whenLaunching.autoPinEdge(.top, to: .bottom, of: paneTitle, withOffset: 18)
whenLaunching.autoPinEdge(.left, to: .right, of: openUntitledWindowTitle, withOffset: 5)
whenLaunching.autoPinEdge(toSuperviewEdge: .right, withInset: 18, relation: .greaterThanOrEqual)
onReactivation.autoPinEdge(.Top, toEdge: .Bottom, ofView: whenLaunching, withOffset: 5)
onReactivation.autoPinEdge(.Left, toEdge: .Left, ofView: whenLaunching)
onReactivation.autoPinEdgeToSuperviewEdge(.Right, withInset: 18, relation: .GreaterThanOrEqual)
onReactivation.autoPinEdge(.top, to: .bottom, of: whenLaunching, withOffset: 5)
onReactivation.autoPinEdge(.left, to: .left, of: whenLaunching)
onReactivation.autoPinEdge(toSuperviewEdge: .right, withInset: 18, relation: .greaterThanOrEqual)
ignoreListTitle.autoAlignAxis(.Baseline, toSameAxisOfView: ignoreField)
ignoreListTitle.autoPinEdge(.Right, toEdge: .Right, ofView: openUntitledWindowTitle)
ignoreListTitle.autoPinEdgeToSuperviewEdge(.Left, withInset: 18, relation: .GreaterThanOrEqual)
ignoreListTitle.autoAlignAxis(.baseline, toSameAxisOf: ignoreField)
ignoreListTitle.autoPinEdge(.right, to: .right, of: openUntitledWindowTitle)
ignoreListTitle.autoPinEdge(toSuperviewEdge: .left, withInset: 18, relation: .greaterThanOrEqual)
ignoreField.autoPinEdge(.Top, toEdge: .Bottom, ofView: onReactivation, withOffset: 18)
ignoreField.autoPinEdgeToSuperviewEdge(.Right, withInset: 18)
ignoreField.autoPinEdge(.Left, toEdge: .Right, ofView: ignoreListTitle, withOffset: 5)
ignoreField.autoPinEdge(.top, to: .bottom, of: onReactivation, withOffset: 18)
ignoreField.autoPinEdge(toSuperviewEdge: .right, withInset: 18)
ignoreField.autoPinEdge(.left, to: .right, of: ignoreListTitle, withOffset: 5)
ignoreInfo.autoPinEdge(.Top, toEdge: .Bottom, ofView: ignoreField, withOffset: 5)
ignoreInfo.autoPinEdgeToSuperviewEdge(.Right, withInset: 18)
ignoreInfo.autoPinEdge(.Left, toEdge: .Right, ofView: ignoreListTitle, withOffset: 5)
ignoreInfo.autoPinEdge(.top, to: .bottom, of: ignoreField, withOffset: 5)
ignoreInfo.autoPinEdge(toSuperviewEdge: .right, withInset: 18)
ignoreInfo.autoPinEdge(.left, to: .right, of: ignoreListTitle, withOffset: 5)
cliToolTitle.autoAlignAxis(.Baseline, toSameAxisOfView: cliToolButton)
cliToolTitle.autoPinEdgeToSuperviewEdge(.Left, withInset: 18, relation: .GreaterThanOrEqual)
cliToolTitle.autoPinEdge(.Right, toEdge: .Right, ofView: openUntitledWindowTitle)
cliToolTitle.autoAlignAxis(.baseline, toSameAxisOf: cliToolButton)
cliToolTitle.autoPinEdge(toSuperviewEdge: .left, withInset: 18, relation: .greaterThanOrEqual)
cliToolTitle.autoPinEdge(.right, to: .right, of: openUntitledWindowTitle)
cliToolButton.autoPinEdge(.Top, toEdge: .Bottom, ofView: ignoreInfo, withOffset: 18)
cliToolButton.autoPinEdgeToSuperviewEdge(.Right, withInset: 18, relation: .GreaterThanOrEqual)
cliToolButton.autoPinEdge(.Left, toEdge: .Right, ofView: cliToolTitle, withOffset: 5)
cliToolButton.autoPinEdge(.top, to: .bottom, of: ignoreInfo, withOffset: 18)
cliToolButton.autoPinEdge(toSuperviewEdge: .right, withInset: 18, relation: .greaterThanOrEqual)
cliToolButton.autoPinEdge(.left, to: .right, of: cliToolTitle, withOffset: 5)
cliToolInfo.autoPinEdge(.Top, toEdge: .Bottom, ofView: cliToolButton, withOffset: 5)
cliToolInfo.autoPinEdgeToSuperviewEdge(.Right, withInset: 18, relation: .GreaterThanOrEqual)
cliToolInfo.autoPinEdge(.Left, toEdge: .Right, ofView: cliToolTitle, withOffset: 5)
cliToolInfo.autoPinEdge(.top, to: .bottom, of: cliToolButton, withOffset: 5)
cliToolInfo.autoPinEdge(toSuperviewEdge: .right, withInset: 18, relation: .greaterThanOrEqual)
cliToolInfo.autoPinEdge(.left, to: .right, of: cliToolTitle, withOffset: 5)
self.openWhenLaunchingCheckbox.boolState = self.data.openNewWindowWhenLaunching
self.openOnReactivationCheckbox.boolState = self.data.openNewWindowOnReactivation
}
override func subscription(source source: Observable<Any>) -> Disposable {
override func subscription(source: Observable<Any>) -> Disposable {
return source
.filter { $0 is PrefData }
.map { ($0 as! PrefData).general }
@ -153,19 +153,19 @@ class GeneralPrefPane: PrefPane, NSTextFieldDelegate {
self.ignorePatternsAction()
}
private func set(data data: GeneralPrefData) {
fileprivate func set(data: GeneralPrefData) {
self.data = data
self.publish(event: data)
}
private func ignoreInfoText() -> NSAttributedString {
let font = NSFont.systemFontOfSize(NSFont.smallSystemFontSize())
fileprivate func ignoreInfoText() -> NSAttributedString {
let font = NSFont.systemFont(ofSize: NSFont.smallSystemFontSize())
let attrs = [
NSFontAttributeName: font,
NSForegroundColorAttributeName: NSColor.grayColor()
NSForegroundColorAttributeName: NSColor.gray
]
let wikiUrl = NSURL(string: "https://github.com/qvacua/vimr/wiki")!
let wikiUrl = URL(string: "https://github.com/qvacua/vimr/wiki")!
let linkStr = NSAttributedString.link(withUrl: wikiUrl, text: "VimR Wiki", font: font)
let str = "Comma-separated list of ignore patterns\n"
+ "Matching files will be ignored in \"Open Quickly\".\n"
@ -173,13 +173,13 @@ class GeneralPrefPane: PrefPane, NSTextFieldDelegate {
+ "For detailed information see "
let ignoreInfoStr = NSMutableAttributedString(string:str, attributes:attrs)
ignoreInfoStr.appendAttributedString(linkStr)
ignoreInfoStr.appendAttributedString(NSAttributedString(string: ".", attributes: attrs))
ignoreInfoStr.append(linkStr)
ignoreInfoStr.append(NSAttributedString(string: ".", attributes: attrs))
return ignoreInfoStr
}
private func updateViews(newData newData: GeneralPrefData) {
fileprivate func updateViews(newData: GeneralPrefData) {
self.openWhenLaunchingCheckbox.boolState = newData.openNewWindowWhenLaunching
self.openOnReactivationCheckbox.boolState = newData.openNewWindowOnReactivation
self.ignoreField.stringValue = PrefUtils.ignorePatternString(fromSet: newData.ignorePatterns)
@ -189,37 +189,37 @@ class GeneralPrefPane: PrefPane, NSTextFieldDelegate {
// MARK: - Actions
extension GeneralPrefPane {
func copyCliTool(sender: NSButton) {
func copyCliTool(_ sender: NSButton) {
let panel = NSOpenPanel()
panel.canChooseFiles = false
panel.canChooseDirectories = true
panel.beginSheetModalForWindow(self.window!) { result in
panel.beginSheetModal(for: self.window!) { result in
guard result == NSFileHandlingPanelOKButton else {
return
}
guard let vimrUrl = NSBundle.mainBundle().URLForResource("vimr", withExtension: nil) else {
guard let vimrUrl = Bundle.main.url(forResource: "vimr", withExtension: nil) else {
self.alert(title: "Something Went Wrong.",
info: "The CLI tool 'vimr' could not be found. Please re-download VimR and try again.")
return
}
guard let targetUrl = panel.URL?.URLByAppendingPathComponent("vimr") else {
guard let targetUrl = panel.url?.appendingPathComponent("vimr") else {
self.alert(title: "Something Went Wrong.",
info: "The target directory could not be determined. Please try again with a different directory.")
return
}
do {
try NSFileManager.defaultManager().copyItemAtURL(vimrUrl, toURL: targetUrl)
try FileManager.default.copyItem(at: vimrUrl, to: targetUrl)
} catch let err as NSError {
self.alert(title: "Error copying 'vimr'", info: err.localizedDescription)
}
}
}
func openUntitledWindowWhenLaunchingAction(sender: NSButton) {
func openUntitledWindowWhenLaunchingAction(_ sender: NSButton) {
self.set(data: GeneralPrefData(
openNewWindowWhenLaunching: self.openWhenLaunchingCheckbox.boolState,
openNewWindowOnReactivation: self.data.openNewWindowOnReactivation,
@ -227,7 +227,7 @@ extension GeneralPrefPane {
)
}
func openUntitledWindowOnReactivationAction(sender: NSButton) {
func openUntitledWindowOnReactivationAction(_ sender: NSButton) {
self.set(data: GeneralPrefData(
openNewWindowWhenLaunching: self.data.openNewWindowWhenLaunching,
openNewWindowOnReactivation: self.openOnReactivationCheckbox.boolState,
@ -235,7 +235,7 @@ extension GeneralPrefPane {
)
}
private func ignorePatternsAction() {
fileprivate func ignorePatternsAction() {
let patterns = PrefUtils.ignorePatterns(fromString: self.ignoreField.stringValue)
if patterns == self.data.ignorePatterns {
return
@ -248,9 +248,9 @@ extension GeneralPrefPane {
)
}
private func alert(title title: String, info: String) {
fileprivate func alert(title: String, info: String) {
let alert = NSAlert()
alert.alertStyle = .WarningAlertStyle
alert.alertStyle = .warning
alert.messageText = title
alert.informativeText = info
alert.runModal()

View File

@ -28,8 +28,8 @@ class ImageAndTextTableCell: NSView {
}
}
private let textField: NSTextField = NSTextField(forAutoLayout: ())
private let imageView: NSImageView = NSImageView(forAutoLayout: ())
fileprivate let textField: NSTextField = NSTextField(forAutoLayout: ())
fileprivate let imageView: NSImageView = NSImageView(forAutoLayout: ())
init(withIdentifier identifier: String) {
super.init(frame: CGRect.zero)
@ -37,9 +37,9 @@ class ImageAndTextTableCell: NSView {
self.identifier = identifier
let textField = self.textField
textField.bordered = false
textField.editable = false
textField.lineBreakMode = .ByTruncatingTail
textField.isBordered = false
textField.isEditable = false
textField.lineBreakMode = .byTruncatingTail
textField.drawsBackground = false
let imageView = self.imageView
@ -47,18 +47,18 @@ class ImageAndTextTableCell: NSView {
self.addSubview(textField)
self.addSubview(imageView)
imageView.autoPinEdgeToSuperviewEdge(.Top, withInset: 2)
imageView.autoPinEdgeToSuperviewEdge(.Left, withInset: 2)
imageView.autoSetDimension(.Width, toSize: 16)
imageView.autoSetDimension(.Height, toSize: 16)
imageView.autoPinEdge(toSuperviewEdge: .top, withInset: 2)
imageView.autoPinEdge(toSuperviewEdge: .left, withInset: 2)
imageView.autoSetDimension(.width, toSize: 16)
imageView.autoSetDimension(.height, toSize: 16)
textField.autoPinEdgeToSuperviewEdge(.Top, withInset: 2)
textField.autoPinEdgeToSuperviewEdge(.Right, withInset: 2)
textField.autoPinEdgeToSuperviewEdge(.Bottom, withInset: 2)
textField.autoPinEdge(.Left, toEdge: .Right, ofView: imageView, withOffset: 4)
textField.autoPinEdge(toSuperviewEdge: .top, withInset: 2)
textField.autoPinEdge(toSuperviewEdge: .right, withInset: 2)
textField.autoPinEdge(toSuperviewEdge: .bottom, withInset: 2)
textField.autoPinEdge(.left, to: .right, of: imageView, withOffset: 4)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
}

View File

@ -15,17 +15,17 @@ enum MainWindowAction {
class MainWindowComponent: WindowComponent, NSWindowDelegate {
private let fontManager = NSFontManager.sharedFontManager()
fileprivate let fontManager = NSFontManager.shared()
private var defaultEditorFont: NSFont
private var usesLigatures: Bool
fileprivate var defaultEditorFont: NSFont
fileprivate var usesLigatures: Bool
var uuid: String {
return self.neoVimView.uuid
}
private var _cwd: NSURL = NSURL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)
var cwd: NSURL {
fileprivate var _cwd: URL = URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)
var cwd: URL {
get {
self._cwd = self.neoVimView.cwd
return self._cwd
@ -43,16 +43,16 @@ class MainWindowComponent: WindowComponent, NSWindowDelegate {
self.fileItemService.monitor(url: newValue)
}
}
private let fileItemService: FileItemService
fileprivate let fileItemService: FileItemService
private let workspace: Workspace
private let neoVimView: NeoVimView
fileprivate let workspace: Workspace
fileprivate let neoVimView: NeoVimView
// TODO: Consider an option object for cwd, urls, etc...
init(source: Observable<Any>,
fileItemService: FileItemService,
cwd: NSURL,
urls: [NSURL] = [],
cwd: URL,
urls: [URL] = [],
initialData: PrefData)
{
self.neoVimView = NeoVimView(frame: CGRect.zero,
@ -83,7 +83,7 @@ class MainWindowComponent: WindowComponent, NSWindowDelegate {
self.show()
}
func open(urls urls: [NSURL]) {
func open(urls: [URL]) {
self.neoVimView.open(urls: urls)
}
@ -104,12 +104,12 @@ class MainWindowComponent: WindowComponent, NSWindowDelegate {
self.workspace.autoPinEdgesToSuperviewEdges()
}
override func subscription(source source: Observable<Any>) -> Disposable {
override func subscription(source: Observable<Any>) -> Disposable {
return source
.filter { $0 is PrefData }
.map { ($0 as! PrefData).appearance }
.filter { [unowned self] appearanceData in
!appearanceData.editorFont.isEqualTo(self.neoVimView.font)
!appearanceData.editorFont.isEqual(to: self.neoVimView.font)
|| appearanceData.editorUsesLigatures != self.neoVimView.usesLigatures
}
.subscribeNext { [unowned self] appearance in
@ -122,28 +122,28 @@ class MainWindowComponent: WindowComponent, NSWindowDelegate {
// MARK: - File Menu Items
extension MainWindowComponent {
@IBAction func newTab(sender: AnyObject!) {
@IBAction func newTab(_ sender: AnyObject!) {
self.neoVimView.newTab()
}
@IBAction func openDocument(sender: AnyObject!) {
@IBAction func openDocument(_ sender: AnyObject!) {
let panel = NSOpenPanel()
panel.canChooseDirectories = true
panel.beginSheetModalForWindow(self.window) { result in
panel.beginSheetModal(for: self.window) { result in
guard result == NSFileHandlingPanelOKButton else {
return
}
// The open panel can choose only one file.
self.neoVimView.open(urls: panel.URLs)
self.neoVimView.open(urls: panel.urls)
}
}
@IBAction func openQuickly(sender: AnyObject!) {
@IBAction func openQuickly(_ sender: AnyObject!) {
self.publish(event: MainWindowAction.openQuickly(mainWindow: self))
}
@IBAction func saveDocument(sender: AnyObject!) {
@IBAction func saveDocument(_ sender: AnyObject!) {
let curBuf = self.neoVimView.currentBuffer()
if curBuf.fileName == nil {
@ -154,7 +154,7 @@ extension MainWindowComponent {
self.neoVimView.saveCurrentTab()
}
@IBAction func saveDocumentAs(sender: AnyObject!) {
@IBAction func saveDocumentAs(_ sender: AnyObject!) {
self.savePanelSheet { url in
self.neoVimView.saveCurrentTab(url: url)
@ -166,24 +166,24 @@ extension MainWindowComponent {
}
}
private func savePanelSheet(action action: (NSURL) -> Void) {
fileprivate func savePanelSheet(action: @escaping (URL) -> Void) {
let panel = NSSavePanel()
panel.beginSheetModalForWindow(self.window) { result in
panel.beginSheetModal(for: self.window) { result in
guard result == NSFileHandlingPanelOKButton else {
return
}
let showAlert: () -> Void = {
let alert = NSAlert()
alert.addButtonWithTitle("OK")
alert.addButton(withTitle: "OK")
alert.messageText = "Invalid File Name"
alert.informativeText = "The file name you have entered cannot be used. Please use a different name."
alert.alertStyle = .WarningAlertStyle
alert.alertStyle = .warning
alert.runModal()
}
guard let url = panel.URL else {
guard let url = panel.url else {
showAlert()
return
}
@ -201,20 +201,20 @@ extension MainWindowComponent {
// MARK: - Font Menu Items
extension MainWindowComponent {
@IBAction func resetFontSize(sender: AnyObject!) {
@IBAction func resetFontSize(_ sender: AnyObject!) {
self.neoVimView.font = self.defaultEditorFont
}
@IBAction func makeFontBigger(sender: AnyObject!) {
@IBAction func makeFontBigger(_ sender: AnyObject!) {
let curFont = self.neoVimView.font
let font = self.fontManager.convertFont(curFont,
let font = self.fontManager.convert(curFont,
toSize: min(curFont.pointSize + 1, PrefStore.maximumEditorFontSize))
self.neoVimView.font = font
}
@IBAction func makeFontSmaller(sender: AnyObject!) {
@IBAction func makeFontSmaller(_ sender: AnyObject!) {
let curFont = self.neoVimView.font
let font = self.fontManager.convertFont(curFont,
let font = self.fontManager.convert(curFont,
toSize: max(curFont.pointSize - 1, PrefStore.minimumEditorFontSize))
self.neoVimView.font = font
}
@ -223,11 +223,11 @@ extension MainWindowComponent {
// MARK: - NeoVimViewDelegate
extension MainWindowComponent: NeoVimViewDelegate {
func setTitle(title: String) {
func setTitle(_ title: String) {
self.window.title = title
}
func setDirtyStatus(dirty: Bool) {
func setDirtyStatus(_ dirty: Bool) {
self.windowController.setDocumentEdited(dirty)
}
@ -246,27 +246,27 @@ extension MainWindowComponent: NeoVimViewDelegate {
// MARK: - NSWindowDelegate
extension MainWindowComponent {
func windowDidBecomeKey(_: NSNotification) {
func windowDidBecomeKey(_: Notification) {
self.publish(event: MainWindowAction.becomeKey(mainWindow: self))
}
func windowWillClose(notification: NSNotification) {
func windowWillClose(_ notification: Notification) {
self.fileItemService.unmonitor(url: self._cwd)
self.publish(event: MainWindowAction.close(mainWindow: self))
}
func windowShouldClose(sender: AnyObject) -> Bool {
func windowShouldClose(_ sender: Any) -> Bool {
if self.neoVimView.isCurrentBufferDirty() {
let alert = NSAlert()
alert.addButtonWithTitle("Cancel")
alert.addButtonWithTitle("Discard and Close")
alert.addButton(withTitle: "Cancel")
alert.addButton(withTitle: "Discard and Close")
alert.messageText = "The current buffer has unsaved changes!"
alert.alertStyle = .WarningAlertStyle
alert.beginSheetModalForWindow(self.window) { response in
alert.alertStyle = .warning
alert.beginSheetModal(for: self.window, completionHandler: { response in
if response == NSAlertSecondButtonReturn {
self.neoVimView.closeCurrentTabWithoutSaving()
}
}
})
return false
}

View File

@ -12,13 +12,13 @@ enum MainWindowEvent {
class MainWindowManager: StandardFlow {
static private let userHomeUrl = NSURL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)
static fileprivate let userHomeUrl = URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true)
private var mainWindowComponents = [String:MainWindowComponent]()
private weak var keyMainWindow: MainWindowComponent?
fileprivate var mainWindowComponents = [String:MainWindowComponent]()
fileprivate weak var keyMainWindow: MainWindowComponent?
private let fileItemService: FileItemService
private var data: PrefData
fileprivate let fileItemService: FileItemService
fileprivate var data: PrefData
init(source: Observable<Any>, fileItemService: FileItemService, initialData: PrefData) {
self.fileItemService = fileItemService
@ -27,7 +27,7 @@ class MainWindowManager: StandardFlow {
super.init(source: source)
}
func newMainWindow(urls urls: [NSURL] = [], cwd: NSURL = MainWindowManager.userHomeUrl) -> MainWindowComponent {
func newMainWindow(urls: [URL] = [], cwd: URL = MainWindowManager.userHomeUrl) -> MainWindowComponent {
let mainWindowComponent = MainWindowComponent(
source: self.source, fileItemService: self.fileItemService, cwd: cwd, urls: urls, initialData: self.data
)
@ -53,12 +53,12 @@ class MainWindowManager: StandardFlow {
return mainWindowComponent
}
func closeMainWindow(mainWindowComponent: MainWindowComponent) {
func closeMainWindow(_ mainWindowComponent: MainWindowComponent) {
if self.keyMainWindow === mainWindowComponent {
self.keyMainWindow = nil
}
self.mainWindowComponents.removeValueForKey(mainWindowComponent.uuid)
self.mainWindowComponents.removeValue(forKey: mainWindowComponent.uuid)
if self.mainWindowComponents.isEmpty {
self.publish(event: MainWindowEvent.allWindowsClosed)
@ -69,7 +69,7 @@ class MainWindowManager: StandardFlow {
return self.mainWindowComponents.values.reduce(false) { $0 ? true : $1.isDirty() }
}
func openInKeyMainWindow(urls urls:[NSURL] = [], cwd: NSURL = MainWindowManager.userHomeUrl) {
func openInKeyMainWindow(urls:[URL] = [], cwd: URL = MainWindowManager.userHomeUrl) {
guard !self.mainWindowComponents.isEmpty else {
self.newMainWindow(urls: urls, cwd: cwd)
return
@ -84,7 +84,7 @@ class MainWindowManager: StandardFlow {
keyMainWindow.open(urls: urls)
}
private func set(keyMainWindow mainWindow: MainWindowComponent?) {
fileprivate func set(keyMainWindow mainWindow: MainWindowComponent?) {
self.keyMainWindow = mainWindow
}
@ -101,7 +101,7 @@ class MainWindowManager: StandardFlow {
return !self.mainWindowComponents.isEmpty
}
override func subscription(source source: Observable<Any>) -> Disposable {
override func subscription(source: Observable<Any>) -> Disposable {
return source
.filter { $0 is PrefData }
.map { $0 as! PrefData }

View File

@ -7,7 +7,7 @@ import Foundation
class Matcher {
static let uppercaseCharSet = NSCharacterSet.uppercaseLetterCharacterSet()
static let uppercaseCharSet = CharacterSet.uppercaseLetters
enum ExactMatchResult {
case none
@ -17,9 +17,9 @@ class Matcher {
case contains
}
static func exactMatchIgnoringCase(target: String, pattern: String) -> ExactMatchResult {
let ltarget = target.lowercaseString
let lpattern = pattern.lowercaseString
static func exactMatchIgnoringCase(_ target: String, pattern: String) -> ExactMatchResult {
let ltarget = target.lowercased()
let lpattern = pattern.lowercased()
if ltarget == lpattern {
return .exact
}
@ -32,26 +32,26 @@ class Matcher {
return .suffix
}
if ltarget.containsString(lpattern) {
if ltarget.contains(lpattern) {
return .contains
}
return .none
}
static func numberOfUppercaseMatches(target: String, pattern: String) -> Int {
var tscalars = target.unicodeScalars.filter { uppercaseCharSet.longCharacterIsMember($0.value) }
static func numberOfUppercaseMatches(_ target: String, pattern: String) -> Int {
var tscalars = target.unicodeScalars.filter { uppercaseCharSet.contains(UnicodeScalar($0.value)!) }
let count = tscalars.count
guard count > 0 else {
return 0
}
let pscalars = pattern.uppercaseString.unicodeScalars
let pscalars = pattern.uppercased().unicodeScalars
pscalars.forEach { scalar in
if let idx = tscalars.indexOf(scalar) {
tscalars.removeAtIndex(idx)
if let idx = tscalars.index(of: scalar) {
tscalars.remove(at: idx)
}
}
@ -60,30 +60,30 @@ class Matcher {
/// Matches `pattern` to `target` in a fuzzy way.
/// - returns: `Array` of `Range<String.UnicodeScalarIndex>`
static func fuzzyIgnoringCase(target: String, pattern: String) -> (matches: Int, ranges: [Range<Int>]) {
let tlower = target.lowercaseString
let plower = pattern.lowercaseString
static func fuzzyIgnoringCase(_ target: String, pattern: String) -> (matches: Int, ranges: [CountableRange<Int>]) {
let tlower = target.lowercased()
let plower = pattern.lowercased()
let tchars = tlower.unicodeScalars
let pchars = plower.unicodeScalars
var flags = Array(count: tchars.count, repeatedValue: false)
var flags = Array(repeating: false, count: tchars.count)
var pidx = pchars.startIndex
for (i, tchar) in tchars.enumerate() {
for (i, tchar) in tchars.enumerated() {
if pchars[pidx] == tchar {
flags[i] = true
pidx = pidx.successor()
pidx = pchars.index(after: pidx)
}
}
var ranges: [Range<Int>] = []
var ranges: [CountableRange<Int>] = []
var matches = 0
var lastTrue = -1
var curTrue = -1
for (i, isTrue) in flags.enumerate() {
for (i, isTrue) in flags.enumerated() {
if isTrue {
matches = matches &+ 1
if lastTrue == -1 {
@ -93,14 +93,14 @@ class Matcher {
if i == flags.count &- 1 {
if lastTrue > -1 && curTrue > -1 {
ranges.append(lastTrue...curTrue)
ranges.append(CountableRange(lastTrue...curTrue))
lastTrue = -1
curTrue = -1
}
}
} else {
if lastTrue > -1 && curTrue > -1 {
ranges.append(lastTrue...curTrue)
ranges.append(CountableRange(lastTrue...curTrue))
lastTrue = -1
curTrue = -1
}
@ -115,23 +115,23 @@ class Matcher {
///
/// - returns: the distance of pattern from target
/// - seealso: https://en.wikipedia.org/wiki/WagnerFischer_algorithm
static func wagnerFisherDistance(target: String, pattern: String) -> Int {
static func wagnerFisherDistance(_ target: String, pattern: String) -> Int {
let s = target.unicodeScalars
let t = pattern.unicodeScalars
let m = s.count
var prevRow = Array(count: m &+ 1, repeatedValue: 0)
var curRow = Array(count: m &+ 1, repeatedValue: 0)
var prevRow = Array(repeating: 0, count: m &+ 1)
var curRow = Array(repeating: 0, count: m &+ 1)
for i in 0...m {
prevRow[i] = i
}
for (j, tchar) in t.enumerate() {
for (j, tchar) in t.enumerated() {
curRow[0] = j &+ 1
for (i, schar) in s.enumerate() {
for (i, schar) in s.enumerated() {
if schar == tchar {
curRow[i &+ 1] = prevRow[i]
} else {

View File

@ -7,18 +7,18 @@ import Cocoa
class OpenQuicklyFileViewRow: NSTableRowView {
override func drawSelectionInRect(dirtyRect: NSRect) {
if self.selected {
NSColor.selectedControlColor().set()
override func drawSelection(in dirtyRect: NSRect) {
if self.isSelected {
NSColor.selectedControlColor.set()
} else {
NSColor.clearColor().set()
NSColor.clear.set()
}
self.rectsBeingDrawn().forEach { NSRectFillUsingOperation(NSIntersectionRect($0, dirtyRect), .CompositeSourceOver) }
self.rectsBeingDrawn().forEach { NSRectFillUsingOperation(NSIntersectionRect($0, dirtyRect), .sourceOver) }
}
private func rectsBeingDrawn() -> [CGRect] {
var rectsPtr: UnsafePointer<CGRect> = nil
fileprivate func rectsBeingDrawn() -> [CGRect] {
var rectsPtr: UnsafePointer<CGRect>? = nil
var count: Int = 0
self.getRectsBeingDrawn(&rectsPtr, count: &count)

View File

@ -5,20 +5,20 @@
import Cocoa
class OpenQuicklyFilterOperation: NSOperation {
class OpenQuicklyFilterOperation: Operation {
private let chunkSize = 100
private let maxResultCount = 500
fileprivate let chunkSize = 100
fileprivate let maxResultCount = 500
private unowned let openQuicklyWindow: OpenQuicklyWindowComponent
private let pattern: String
private let flatFileItems: [FileItem]
private let cwd: NSURL
fileprivate unowned let openQuicklyWindow: OpenQuicklyWindowComponent
fileprivate let pattern: String
fileprivate let flatFileItems: [FileItem]
fileprivate let cwd: URL
init(forOpenQuicklyWindow openQuicklyWindow: OpenQuicklyWindowComponent) {
self.openQuicklyWindow = openQuicklyWindow
self.pattern = openQuicklyWindow.pattern
self.cwd = openQuicklyWindow.cwd
self.cwd = openQuicklyWindow.cwd as URL
self.flatFileItems = openQuicklyWindow.flatFileItems
super.init()
@ -33,7 +33,7 @@ class OpenQuicklyFilterOperation: NSOperation {
self.openQuicklyWindow.scanCondition.unlock()
}
if self.cancelled {
if self.isCancelled {
return
}
@ -47,17 +47,17 @@ class OpenQuicklyFilterOperation: NSOperation {
let count = self.flatFileItems.count
let chunksCount = Int(ceil(Float(count) / Float(self.chunkSize)))
let useFullPath = pattern.containsString("/")
let cwdPath = self.cwd.path! + "/"
let useFullPath = pattern.contains("/")
let cwdPath = self.cwd.path + "/"
var result = [ScoredFileItem]()
var spinLock = OS_SPINLOCK_INIT
let cleanedPattern = useFullPath ? self.pattern.stringByReplacingOccurrencesOfString("/", withString: "")
let cleanedPattern = useFullPath ? self.pattern.replacingOccurrences(of: "/", with: "")
: self.pattern
dispatch_apply(chunksCount, dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) { [unowned self] idx in
if self.cancelled {
DispatchQueue.concurrentPerform(iterations: chunksCount) { [unowned self] idx in
if self.isCancelled {
return
}
@ -66,39 +66,39 @@ class OpenQuicklyFilterOperation: NSOperation {
let chunkedItems = self.flatFileItems[startIndex..<endIndex]
let chunkedResult: [ScoredFileItem] = chunkedItems.flatMap {
if self.cancelled {
if self.isCancelled {
return nil
}
let url = $0.url
if useFullPath {
let target = url.path!.stringByReplacingOccurrencesOfString(cwdPath, withString: "")
.stringByReplacingOccurrencesOfString("/", withString: "")
let target = url.path.replacingOccurrences(of: cwdPath, with: "")
.replacingOccurrences(of: "/", with: "")
return ScoredFileItem(score: Scorer.score(target, pattern: cleanedPattern), url: url)
}
return ScoredFileItem(score: Scorer.score(url.lastPathComponent!, pattern: cleanedPattern), url: url)
return ScoredFileItem(score: Scorer.score(url.lastPathComponent, pattern: cleanedPattern), url: url)
}
if self.cancelled {
if self.isCancelled {
return
}
OSSpinLockLock(&spinLock)
result.appendContentsOf(chunkedResult)
result.append(contentsOf: chunkedResult)
OSSpinLockUnlock(&spinLock)
}
if self.cancelled {
if self.isCancelled {
return
}
sorted = result.sort(>)
sorted = result.sorted(by: >)
}
if self.cancelled {
if self.isCancelled {
return
}
@ -107,4 +107,4 @@ class OpenQuicklyFilterOperation: NSOperation {
self.openQuicklyWindow.reloadFileView(withScoredItems: result)
}
}
}
}

View File

@ -16,80 +16,80 @@ class OpenQuicklyWindowComponent: WindowComponent,
let scanCondition = NSCondition()
var pauseScan = false
private(set) var pattern = ""
private(set) var cwd = NSURL(fileURLWithPath: NSHomeDirectory(), isDirectory: true) {
fileprivate(set) var pattern = ""
fileprivate(set) var cwd = URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true) {
didSet {
self.cwdPathCompsCount = self.cwd.pathComponents!.count
self.cwdControl.URL = self.cwd
self.cwdPathCompsCount = self.cwd.pathComponents.count
self.cwdControl.url = self.cwd
}
}
private(set) var flatFileItems = [FileItem]()
private(set) var fileViewItems = [ScoredFileItem]()
fileprivate(set) var flatFileItems = [FileItem]()
fileprivate(set) var fileViewItems = [ScoredFileItem]()
private let userInitiatedScheduler = ConcurrentDispatchQueueScheduler(globalConcurrentQueueQOS: .UserInitiated)
fileprivate let userInitiatedScheduler = ConcurrentDispatchQueueScheduler(globalConcurrentQueueQOS: .userInitiated)
private let searchField = NSTextField(forAutoLayout: ())
private let progressIndicator = NSProgressIndicator(forAutoLayout: ())
private let cwdControl = NSPathControl(forAutoLayout: ())
private let countField = NSTextField(forAutoLayout: ())
private let fileView = NSTableView.standardTableView()
fileprivate let searchField = NSTextField(forAutoLayout: ())
fileprivate let progressIndicator = NSProgressIndicator(forAutoLayout: ())
fileprivate let cwdControl = NSPathControl(forAutoLayout: ())
fileprivate let countField = NSTextField(forAutoLayout: ())
fileprivate let fileView = NSTableView.standardTableView()
private let fileItemService: FileItemService
fileprivate let fileItemService: FileItemService
private var count = 0
private var perSessionDisposeBag = DisposeBag()
fileprivate var count = 0
fileprivate var perSessionDisposeBag = DisposeBag()
private var cwdPathCompsCount = 0
private let searchStream: Observable<String>
private let filterOpQueue = NSOperationQueue()
fileprivate var cwdPathCompsCount = 0
fileprivate let searchStream: Observable<String>
fileprivate let filterOpQueue = OperationQueue()
weak private var mainWindow: MainWindowComponent?
weak fileprivate var mainWindow: MainWindowComponent?
init(source: Observable<Any>, fileItemService: FileItemService) {
self.fileItemService = fileItemService
self.searchStream = self.searchField.rx_text
self.searchStream = self.searchField.rx.textInput.text
.throttle(0.2, scheduler: MainScheduler.instance)
.distinctUntilChanged()
super.init(source: source, nibName: "OpenQuicklyWindow")
self.window.delegate = self
self.filterOpQueue.qualityOfService = .UserInitiated
self.filterOpQueue.qualityOfService = .userInitiated
self.filterOpQueue.name = "open-quickly-filter-operation-queue"
}
override func addViews() {
let searchField = self.searchField
searchField.rx_delegate.setForwardToDelegate(self, retainDelegate: false)
searchField.rx.delegate.setForwardToDelegate(self, retainDelegate: false)
let progressIndicator = self.progressIndicator
progressIndicator.indeterminate = true
progressIndicator.displayedWhenStopped = false
progressIndicator.style = .SpinningStyle
progressIndicator.controlSize = .SmallControlSize
progressIndicator.isIndeterminate = true
progressIndicator.isDisplayedWhenStopped = false
progressIndicator.style = .spinningStyle
progressIndicator.controlSize = .small
let fileView = self.fileView
fileView.intercellSpacing = CGSize(width: 4, height: 4)
fileView.setDataSource(self)
fileView.setDelegate(self)
fileView.dataSource = self
fileView.delegate = self
let fileScrollView = NSScrollView.standardScrollView()
fileScrollView.autoresizesSubviews = true
fileScrollView.documentView = fileView
let cwdControl = self.cwdControl
cwdControl.pathStyle = .Standard
cwdControl.backgroundColor = NSColor.clearColor()
cwdControl.pathStyle = .standard
cwdControl.backgroundColor = NSColor.clear
cwdControl.refusesFirstResponder = true
cwdControl.cell?.controlSize = .SmallControlSize
cwdControl.cell?.font = NSFont.systemFontOfSize(NSFont.smallSystemFontSize())
cwdControl.setContentCompressionResistancePriority(NSLayoutPriorityDefaultLow, forOrientation:.Horizontal)
cwdControl.cell?.controlSize = .small
cwdControl.cell?.font = NSFont.systemFont(ofSize: NSFont.smallSystemFontSize())
cwdControl.setContentCompressionResistancePriority(NSLayoutPriorityDefaultLow, for:.horizontal)
let countField = self.countField
countField.editable = false
countField.bordered = false
countField.alignment = .Right
countField.backgroundColor = NSColor.clearColor()
countField.isEditable = false
countField.isBordered = false
countField.alignment = .right
countField.backgroundColor = NSColor.clear
countField.stringValue = "0 items"
let contentView = self.window.contentView!
@ -99,28 +99,28 @@ class OpenQuicklyWindowComponent: WindowComponent,
contentView.addSubview(cwdControl)
contentView.addSubview(countField)
searchField.autoPinEdgeToSuperviewEdge(.Top, withInset: 8)
searchField.autoPinEdgeToSuperviewEdge(.Right, withInset: 8)
searchField.autoPinEdgeToSuperviewEdge(.Left, withInset: 8)
searchField.autoPinEdge(toSuperviewEdge: .top, withInset: 8)
searchField.autoPinEdge(toSuperviewEdge: .right, withInset: 8)
searchField.autoPinEdge(toSuperviewEdge: .left, withInset: 8)
progressIndicator.autoAlignAxis(.Horizontal, toSameAxisOfView: searchField)
progressIndicator.autoPinEdge(.Right, toEdge: .Right, ofView: searchField, withOffset: -4)
progressIndicator.autoAlignAxis(.horizontal, toSameAxisOf: searchField)
progressIndicator.autoPinEdge(.right, to: .right, of: searchField, withOffset: -4)
fileScrollView.autoPinEdge(.Top, toEdge: .Bottom, ofView: searchField, withOffset: 8)
fileScrollView.autoPinEdgeToSuperviewEdge(.Left, withInset: -1)
fileScrollView.autoPinEdgeToSuperviewEdge(.Right, withInset: -1)
fileScrollView.autoSetDimension(.Height, toSize: 200, relation: .GreaterThanOrEqual)
fileScrollView.autoPinEdge(.top, to: .bottom, of: searchField, withOffset: 8)
fileScrollView.autoPinEdge(toSuperviewEdge: .left, withInset: -1)
fileScrollView.autoPinEdge(toSuperviewEdge: .right, withInset: -1)
fileScrollView.autoSetDimension(.height, toSize: 200, relation: .greaterThanOrEqual)
cwdControl.autoPinEdge(.Top, toEdge: .Bottom, ofView: fileScrollView, withOffset: 4)
cwdControl.autoPinEdgeToSuperviewEdge(.Left, withInset: 2)
cwdControl.autoPinEdgeToSuperviewEdge(.Bottom, withInset: 4)
cwdControl.autoPinEdge(.top, to: .bottom, of: fileScrollView, withOffset: 4)
cwdControl.autoPinEdge(toSuperviewEdge: .left, withInset: 2)
cwdControl.autoPinEdge(toSuperviewEdge: .bottom, withInset: 4)
countField.autoPinEdge(.Top, toEdge: .Bottom, ofView: fileScrollView, withOffset: 4)
countField.autoPinEdgeToSuperviewEdge(.Right, withInset: 2)
countField.autoPinEdge(.Left, toEdge: .Right, ofView: cwdControl, withOffset: 4)
countField.autoPinEdge(.top, to: .bottom, of: fileScrollView, withOffset: 4)
countField.autoPinEdge(toSuperviewEdge: .right, withInset: 2)
countField.autoPinEdge(.left, to: .right, of: cwdControl, withOffset: 4)
}
override func subscription(source source: Observable<Any>) -> Disposable {
override func subscription(source: Observable<Any>) -> Disposable {
return NopDisposable.instance
}
@ -154,7 +154,7 @@ class OpenQuicklyWindowComponent: WindowComponent,
}
.addDisposableTo(self.perSessionDisposeBag)
self.cwd = mainWindow.cwd
self.cwd = mainWindow.cwd as URL
let flatFiles = self.fileItemService.flatFileItems(ofUrl: self.cwd)
.subscribeOn(self.userInitiatedScheduler)
@ -174,7 +174,7 @@ class OpenQuicklyWindowComponent: WindowComponent,
}
self.scanCondition.unlock()
self.flatFileItems.appendContentsOf(items)
self.flatFileItems.append(contentsOf: items)
self.resetAndAddFilterOperation()
}
.observeOn(MainScheduler.instance)
@ -188,7 +188,7 @@ class OpenQuicklyWindowComponent: WindowComponent,
self.searchField.becomeFirstResponder()
}
private func resetAndAddFilterOperation() {
fileprivate func resetAndAddFilterOperation() {
self.filterOpQueue.cancelAllOperations()
let op = OpenQuicklyFilterOperation(forOpenQuicklyWindow: self)
self.filterOpQueue.addOperation(op)
@ -198,7 +198,7 @@ class OpenQuicklyWindowComponent: WindowComponent,
// MARK: - NSTableViewDataSource
extension OpenQuicklyWindowComponent {
func numberOfRowsInTableView(_: NSTableView) -> Int {
@objc(numberOfRowsInTableView:) func numberOfRows(in _: NSTableView) -> Int {
return self.fileViewItems.count
}
}
@ -206,27 +206,27 @@ extension OpenQuicklyWindowComponent {
// MARK: - NSTableViewDelegate
extension OpenQuicklyWindowComponent {
func tableView(tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
return OpenQuicklyFileViewRow()
}
func tableView(tableView: NSTableView, viewForTableColumn _: NSTableColumn?, row: Int) -> NSView? {
let cachedCell = tableView.makeViewWithIdentifier("file-view-row", owner: self)
@objc(tableView:viewForTableColumn:row:) func tableView(_ tableView: NSTableView, viewFor _: NSTableColumn?, row: Int) -> NSView? {
let cachedCell = tableView.make(withIdentifier: "file-view-row", owner: self)
let cell = cachedCell as? ImageAndTextTableCell ?? ImageAndTextTableCell(withIdentifier: "file-view-row")
let url = self.fileViewItems[row].url
cell.text = self.rowText(forUrl: url)
cell.text = self.rowText(forUrl: url as URL)
cell.image = self.fileItemService.icon(forUrl: url)
return cell
}
func tableViewSelectionDidChange(_: NSNotification) {
func tableViewSelectionDidChange(_: Notification) {
// NSLog("\(#function): selection changed")
}
private func rowText(forUrl url: NSURL) -> NSAttributedString {
let pathComps = url.pathComponents!
fileprivate func rowText(forUrl url: URL) -> NSAttributedString {
let pathComps = url.pathComponents
let truncatedPathComps = pathComps[self.cwdPathCompsCount..<pathComps.count]
let name = truncatedPathComps.last!
@ -235,10 +235,10 @@ extension OpenQuicklyWindowComponent {
}
let rowText: NSMutableAttributedString
let pathInfo = truncatedPathComps.dropLast().reverse().joinWithSeparator(" / ")
let pathInfo = truncatedPathComps.dropLast().reversed().joined(separator: " / ")
rowText = NSMutableAttributedString(string: "\(name)\(pathInfo)")
rowText.addAttribute(NSForegroundColorAttributeName,
value: NSColor.lightGrayColor(),
value: NSColor.lightGray,
range: NSRange(location:name.characters.count,
length: pathInfo.characters.count + 3))
@ -249,7 +249,7 @@ extension OpenQuicklyWindowComponent {
// MARK: - NSTextFieldDelegate
extension OpenQuicklyWindowComponent {
func control(control: NSControl, textView: NSTextView, doCommandBySelector commandSelector: Selector) -> Bool {
@objc(control:textView:doCommandBySelector:) func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
switch commandSelector {
case NSSelectorFromString("cancelOperation:"):
self.window.performClose(self)
@ -273,7 +273,7 @@ extension OpenQuicklyWindowComponent {
}
}
private func moveSelection(ofTableView tableView: NSTableView, byDelta delta: Int) {
fileprivate func moveSelection(ofTableView tableView: NSTableView, byDelta delta: Int) {
let selectedRow = tableView.selectedRow
let lastIdx = tableView.numberOfRows - 1
let targetIdx: Int
@ -286,7 +286,7 @@ extension OpenQuicklyWindowComponent {
targetIdx = selectedRow + delta
}
tableView.selectRowIndexes(NSIndexSet(index: targetIdx), byExtendingSelection: false)
tableView.selectRowIndexes(IndexSet(integer: targetIdx), byExtendingSelection: false)
tableView.scrollRowToVisible(targetIdx)
}
}
@ -294,7 +294,7 @@ extension OpenQuicklyWindowComponent {
// MARK: - NSWindowDelegate
extension OpenQuicklyWindowComponent {
func windowWillClose(notification: NSNotification) {
func windowWillClose(_ notification: Notification) {
self.endProgress()
self.mainWindow = nil
@ -314,7 +314,7 @@ extension OpenQuicklyWindowComponent {
self.countField.stringValue = "0 items"
}
func windowDidResignKey(notification: NSNotification) {
func windowDidResignKey(_ notification: Notification) {
self.window.performClose(self)
}
}

View File

@ -8,8 +8,8 @@ import RxSwift
class OpenQuicklyWindowManager: StandardFlow {
private let openQuicklyWindow: OpenQuicklyWindowComponent
private let fileItemService: FileItemService
fileprivate let openQuicklyWindow: OpenQuicklyWindowComponent
fileprivate let fileItemService: FileItemService
init(source: Observable<Any>, fileItemService: FileItemService) {
self.fileItemService = fileItemService
@ -22,7 +22,7 @@ class OpenQuicklyWindowManager: StandardFlow {
self.openQuicklyWindow.show(forMainWindow: mainWindow)
}
override func subscription(source source: Observable<Any>) -> Disposable {
override func subscription(source: Observable<Any>) -> Disposable {
return NopDisposable.instance
}
}

View File

@ -10,15 +10,15 @@ class PrefPane: NSView, Component {
let disposeBag = DisposeBag()
private let source: Observable<Any>
fileprivate let source: Observable<Any>
private let subject = PublishSubject<Any>()
fileprivate let subject = PublishSubject<Any>()
var sink: Observable<Any> {
return self.subject.asObservable()
}
// Return true to place this to the upper left corner when the scroll view is bigger than this view.
override var flipped: Bool {
override var isFlipped: Bool {
return true
}
@ -52,11 +52,11 @@ class PrefPane: NSView, Component {
preconditionFailure("Please override")
}
func subscription(source source: Observable<Any>) -> Disposable {
func subscription(source: Observable<Any>) -> Disposable {
preconditionFailure("Please override")
}
func publish(event event: Any) {
func publish(event: Any) {
self.subject.onNext(event)
}
@ -68,31 +68,31 @@ class PrefPane: NSView, Component {
// MARK: - Control Utils
extension PrefPane {
func paneTitleTextField(title title: String) -> NSTextField {
func paneTitleTextField(title: String) -> NSTextField {
let field = defaultTitleTextField()
field.font = NSFont.boldSystemFontOfSize(16)
field.alignment = .Left;
field.font = NSFont.boldSystemFont(ofSize: 16)
field.alignment = .left;
field.stringValue = title
return field
}
func titleTextField(title title: String) -> NSTextField {
func titleTextField(title: String) -> NSTextField {
let field = defaultTitleTextField()
field.alignment = .Right;
field.alignment = .right;
field.stringValue = title
return field
}
func infoTextField(text text: String) -> NSTextField {
func infoTextField(text: String) -> NSTextField {
let field = NSTextField(forAutoLayout: ())
field.font = NSFont.systemFontOfSize(NSFont.smallSystemFontSize())
field.textColor = NSColor.grayColor()
field.backgroundColor = NSColor.clearColor()
field.editable = false
field.bordered = false
field.font = NSFont.systemFont(ofSize: NSFont.smallSystemFontSize())
field.textColor = NSColor.gray
field.backgroundColor = NSColor.clear
field.isEditable = false
field.isBordered = false
// both are needed, otherwise hyperlink won't accept mousedown
field.selectable = true
field.isSelectable = true
field.allowsEditingTextAttributes = true
field.stringValue = text
@ -100,19 +100,19 @@ extension PrefPane {
return field
}
func configureCheckbox(button button: NSButton, title: String, action: Selector) {
func configureCheckbox(button: NSButton, title: String, action: Selector) {
button.title = title
button.setButtonType(.SwitchButton)
button.bezelStyle = .ThickSquareBezelStyle
button.setButtonType(.switch)
// button.bezelStyle = .ThickSquareBezelStyle
button.target = self
button.action = action
}
private func defaultTitleTextField() -> NSTextField {
fileprivate func defaultTitleTextField() -> NSTextField {
let field = NSTextField(forAutoLayout: ())
field.backgroundColor = NSColor.clearColor();
field.editable = false;
field.bordered = false;
field.backgroundColor = NSColor.clear;
field.isEditable = false;
field.isBordered = false;
return field
}
}

View File

@ -21,21 +21,21 @@ private class PrefKeys {
class PrefStore: Store {
private static let compatibleVersion = "38"
private static let defaultEditorFont = NeoVimView.defaultFont
fileprivate static let compatibleVersion = "38"
fileprivate static let defaultEditorFont = NeoVimView.defaultFont
static let minimumEditorFontSize = NeoVimView.minFontSize
static let maximumEditorFontSize = NeoVimView.maxFontSize
private let source: Observable<Any>
private let disposeBag = DisposeBag()
fileprivate let source: Observable<Any>
fileprivate let disposeBag = DisposeBag()
private let subject = PublishSubject<Any>()
fileprivate let subject = PublishSubject<Any>()
var sink: Observable<Any> {
return self.subject.asObservable()
}
private let userDefaults = NSUserDefaults.standardUserDefaults()
private let fontManager = NSFontManager.sharedFontManager()
fileprivate let userDefaults = UserDefaults.standard
fileprivate let fontManager = NSFontManager.shared()
var data = PrefData(
general: GeneralPrefData(openNewWindowWhenLaunching: true,
@ -48,7 +48,7 @@ class PrefStore: Store {
init(source: Observable<Any>) {
self.source = source
if let prefs = self.userDefaults.dictionaryForKey(PrefStore.compatibleVersion) {
if let prefs = self.userDefaults.dictionary(forKey: PrefStore.compatibleVersion) {
self.data = self.prefDataFromDict(prefs)
} else {
self.userDefaults.setValue(self.prefsDict(self.data), forKey: PrefStore.compatibleVersion)
@ -61,7 +61,7 @@ class PrefStore: Store {
self.subject.onCompleted()
}
private func prefDataFromDict(prefs: [String: AnyObject]) -> PrefData {
fileprivate func prefDataFromDict(_ prefs: [String: Any]) -> PrefData {
let editorFontName = prefs[PrefKeys.editorFontName] as? String ?? PrefStore.defaultEditorFont.fontName
let editorFontSize = CGFloat(
@ -89,43 +89,43 @@ class PrefStore: Store {
)
}
private func saneFont(fontName: String, fontSize: CGFloat) -> NSFont {
fileprivate func saneFont(_ fontName: String, fontSize: CGFloat) -> NSFont {
var editorFont = NSFont(name: fontName, size: fontSize) ?? PrefStore.defaultEditorFont
if !editorFont.fixedPitch {
editorFont = fontManager.convertFont(PrefStore.defaultEditorFont, toSize: editorFont.pointSize)
if !editorFont.isFixedPitch {
editorFont = fontManager.convert(PrefStore.defaultEditorFont, toSize: editorFont.pointSize)
}
if editorFont.pointSize < PrefStore.minimumEditorFontSize
|| editorFont.pointSize > PrefStore.maximumEditorFontSize {
editorFont = fontManager.convertFont(editorFont, toSize: PrefStore.defaultEditorFont.pointSize)
editorFont = fontManager.convert(editorFont, toSize: PrefStore.defaultEditorFont.pointSize)
}
return editorFont
}
private func prefsDict(prefData: PrefData) -> [String: AnyObject] {
fileprivate func prefsDict(_ prefData: PrefData) -> [String: AnyObject] {
let generalData = prefData.general
let appearanceData = prefData.appearance
let advancedData = prefData.advanced
let prefs: [String: AnyObject] = [
// General
PrefKeys.openNewWindowWhenLaunching: generalData.openNewWindowWhenLaunching,
PrefKeys.openNewWindowOnReactivation: generalData.openNewWindowOnReactivation,
PrefKeys.openQuicklyIgnorePatterns: PrefUtils.ignorePatternString(fromSet: generalData.ignorePatterns),
PrefKeys.openNewWindowWhenLaunching: generalData.openNewWindowWhenLaunching as AnyObject,
PrefKeys.openNewWindowOnReactivation: generalData.openNewWindowOnReactivation as AnyObject,
PrefKeys.openQuicklyIgnorePatterns: PrefUtils.ignorePatternString(fromSet: generalData.ignorePatterns) as AnyObject,
// Appearance
PrefKeys.editorFontName: appearanceData.editorFont.fontName,
PrefKeys.editorFontSize: appearanceData.editorFont.pointSize,
PrefKeys.editorUsesLigatures: appearanceData.editorUsesLigatures,
PrefKeys.editorFontName: appearanceData.editorFont.fontName as AnyObject,
PrefKeys.editorFontSize: appearanceData.editorFont.pointSize as AnyObject,
PrefKeys.editorUsesLigatures: appearanceData.editorUsesLigatures as AnyObject,
// Advanced
PrefKeys.useInteractiveZsh: advancedData.useInteractiveZsh,
PrefKeys.useInteractiveZsh: advancedData.useInteractiveZsh as AnyObject,
]
return prefs
}
private func addReactions() {
fileprivate func addReactions() {
self.source
.filter { $0 is PrefData }
.map { $0 as! PrefData }

View File

@ -7,17 +7,17 @@ import Foundation
class PrefUtils {
private static let whitespaceCharSet = NSCharacterSet.whitespaceCharacterSet()
fileprivate static let whitespaceCharSet = CharacterSet.whitespaces
static func ignorePatterns(fromString str: String) -> Set<FileItemIgnorePattern> {
if str.stringByTrimmingCharactersInSet(self.whitespaceCharSet).characters.count == 0 {
if str.trimmingCharacters(in: self.whitespaceCharSet).characters.count == 0 {
return Set()
}
let patterns: [FileItemIgnorePattern] = str
.componentsSeparatedByString(",")
.components(separatedBy: ",")
.flatMap {
let trimmed = $0.stringByTrimmingCharactersInSet(self.whitespaceCharSet)
let trimmed = $0.trimmingCharacters(in: self.whitespaceCharSet)
if trimmed.characters.count == 0 {
return nil
}
@ -31,7 +31,7 @@ class PrefUtils {
static func ignorePatternString(fromSet set: Set<FileItemIgnorePattern>) -> String {
return Array(set)
.map { $0.pattern }
.sort()
.joinWithSeparator(", ")
.sorted()
.joined(separator: ", ")
}
}
}

View File

@ -15,14 +15,14 @@ struct PrefData {
class PrefWindowComponent: WindowComponent, NSWindowDelegate, NSTableViewDataSource, NSTableViewDelegate {
private var data: PrefData
fileprivate var data: PrefData
private let categoryView = NSTableView.standardSourceListTableView()
private let categoryScrollView = NSScrollView.standardScrollView()
private let paneContainer = NSScrollView(forAutoLayout: ())
fileprivate let categoryView = NSTableView.standardSourceListTableView()
fileprivate let categoryScrollView = NSScrollView.standardScrollView()
fileprivate let paneContainer = NSScrollView(forAutoLayout: ())
private let panes: [PrefPane]
private var currentPane: PrefPane {
fileprivate let panes: [PrefPane]
fileprivate var currentPane: PrefPane {
get {
return self.paneContainer.documentView as! PrefPane
}
@ -53,7 +53,7 @@ class PrefWindowComponent: WindowComponent, NSWindowDelegate, NSTableViewDataSou
self.addReactions()
}
override func subscription(source source: Observable<Any>) -> Disposable {
override func subscription(source: Observable<Any>) -> Disposable {
return source
.filter { $0 is PrefData }
.map { $0 as! PrefData }
@ -69,8 +69,8 @@ class PrefWindowComponent: WindowComponent, NSWindowDelegate, NSTableViewDataSou
override func addViews() {
let categoryView = self.categoryView
categoryView.setDataSource(self)
categoryView.setDelegate(self)
categoryView.dataSource = self
categoryView.delegate = self
let categoryScrollView = self.categoryScrollView
categoryScrollView.documentView = categoryView
@ -79,28 +79,28 @@ class PrefWindowComponent: WindowComponent, NSWindowDelegate, NSTableViewDataSou
paneContainer.hasVerticalScroller = true
paneContainer.hasHorizontalScroller = true
paneContainer.autohidesScrollers = true
paneContainer.borderType = .NoBorder
paneContainer.borderType = .noBorder
paneContainer.autoresizesSubviews = false
paneContainer.backgroundColor = NSColor.windowBackgroundColor()
paneContainer.backgroundColor = NSColor.windowBackgroundColor
self.window.contentView?.addSubview(categoryScrollView)
self.window.contentView?.addSubview(paneContainer)
categoryScrollView.autoSetDimension(.Width, toSize: 150)
categoryScrollView.autoPinEdgeToSuperviewEdge(.Top, withInset: -1)
categoryScrollView.autoPinEdgeToSuperviewEdge(.Bottom, withInset: -1)
categoryScrollView.autoPinEdgeToSuperviewEdge(.Left, withInset: -1)
categoryScrollView.autoSetDimension(.width, toSize: 150)
categoryScrollView.autoPinEdge(toSuperviewEdge: .top, withInset: -1)
categoryScrollView.autoPinEdge(toSuperviewEdge: .bottom, withInset: -1)
categoryScrollView.autoPinEdge(toSuperviewEdge: .left, withInset: -1)
paneContainer.autoSetDimension(.Width, toSize: 200, relation: .GreaterThanOrEqual)
paneContainer.autoPinEdgeToSuperviewEdge(.Top)
paneContainer.autoPinEdgeToSuperviewEdge(.Right)
paneContainer.autoPinEdgeToSuperviewEdge(.Bottom)
paneContainer.autoPinEdge(.Left, toEdge: .Right, ofView: categoryScrollView)
paneContainer.autoSetDimension(.width, toSize: 200, relation: .greaterThanOrEqual)
paneContainer.autoPinEdge(toSuperviewEdge: .top)
paneContainer.autoPinEdge(toSuperviewEdge: .right)
paneContainer.autoPinEdge(toSuperviewEdge: .bottom)
paneContainer.autoPinEdge(.left, to: .right, of: categoryScrollView)
self.currentPane = self.panes[0]
}
private func addReactions() {
fileprivate func addReactions() {
self.panes
.map { $0.sink }
.toMergedObservables()
@ -122,7 +122,7 @@ class PrefWindowComponent: WindowComponent, NSWindowDelegate, NSTableViewDataSou
.addDisposableTo(self.disposeBag)
}
func windowWillClose(notification: NSNotification) {
func windowWillClose(_ notification: Notification) {
self.panes.forEach { $0.windowWillClose() }
}
}
@ -130,11 +130,11 @@ class PrefWindowComponent: WindowComponent, NSWindowDelegate, NSTableViewDataSou
// MARK: - NSTableViewDataSource
extension PrefWindowComponent {
func numberOfRowsInTableView(_: NSTableView) -> Int {
@objc(numberOfRowsInTableView:) func numberOfRows(in _: NSTableView) -> Int {
return self.panes.count
}
func tableView(_: NSTableView, objectValueForTableColumn _: NSTableColumn?, row: Int) -> AnyObject? {
@objc(tableView:objectValueForTableColumn:row:) func tableView(_: NSTableView, objectValueFor _: NSTableColumn?, row: Int) -> Any? {
return self.panes[row].displayName
}
}
@ -142,7 +142,7 @@ extension PrefWindowComponent {
// MARK: - NSTableViewDelegate
extension PrefWindowComponent {
func tableViewSelectionDidChange(_: NSNotification) {
func tableViewSelectionDidChange(_: Notification) {
let idx = self.categoryView.selectedRow
self.currentPane = self.panes[idx]
}

View File

@ -8,9 +8,9 @@ import RxSwift
class ScoredFileItem: Comparable {
let score: Int
unowned let url: NSURL
let url: URL
init(score: Int, url: NSURL) {
init(score: Int, url: URL) {
self.score = score
self.url = url
}

View File

@ -7,7 +7,7 @@ import Foundation
class Scorer {
static func score(target: String, pattern: String) -> Int {
static func score(_ target: String, pattern: String) -> Int {
let wf = Matcher.wagnerFisherDistance(target, pattern: pattern)
let fuzzy = Matcher.fuzzyIgnoringCase(target, pattern: pattern)
let upper = Matcher.numberOfUppercaseMatches(target, pattern: pattern)

View File

@ -5,17 +5,17 @@
import Foundation
func call(@autoclosure closure: () -> Void, when condition: Bool) { if condition { closure() } }
func call(@autoclosure closure: () -> Void, whenNot condition: Bool) { if !condition { closure() } }
func call(_ closure: @autoclosure () -> Void, when condition: Bool) { if condition { closure() } }
func call(_ closure: @autoclosure () -> Void, whenNot condition: Bool) { if !condition { closure() } }
extension String {
func without(prefix prefix: String) -> String {
func without(prefix: String) -> String {
guard self.hasPrefix(prefix) else {
return self
}
let idx = self.startIndex.advancedBy(prefix.characters.count)
let idx = self.characters.index(self.startIndex, offsetBy: prefix.characters.count)
return self[idx..<self.endIndex]
}
}
@ -30,8 +30,8 @@ extension Array {
/// - transform: The transform function.
/// - returns: Transformed array of `self`.
func concurrentChunkMap<R>(
chunk: Int = 100,
queue: dispatch_queue_t = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0),
_ chunk: Int = 100,
queue: DispatchQueue = DispatchQueue.global(qos: DispatchQoS.QoSClass.userInitiated),
transform: (Element) -> R) -> [R]
{
let count = self.count
@ -41,9 +41,9 @@ extension Array {
var spinLock = OS_SPINLOCK_INIT
dispatch_apply(chunkedCount, queue) { idx in
let startIndex = min(idx * chunk, count)
let endIndex = min(startIndex + chunk, count)
DispatchQueue.concurrentPerform(iterations: chunkedCount) { idx in
let startIndex = Swift.min(idx * chunk, count)
let endIndex = Swift.min(startIndex + chunk, count)
let mappedChunk = self[startIndex..<endIndex].map(transform)
@ -54,4 +54,4 @@ extension Array {
return result.flatMap { $0 }
}
}
}

View File

@ -19,13 +19,13 @@ class Workspace: NSView {
let mainViewMinimumSize: CGSize
}
private(set) var isBarVisible = true {
fileprivate(set) var isBarVisible = true {
didSet {
self.relayout()
}
}
private let bars: [WorkspaceBarLocation: WorkspaceBar]
fileprivate let bars: [WorkspaceBarLocation: WorkspaceBar]
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
@ -52,7 +52,7 @@ class Workspace: NSView {
self.relayout()
}
func append(tool tool: WorkspaceTool, location: WorkspaceBarLocation) {
func append(tool: WorkspaceTool, location: WorkspaceBarLocation) {
self.bars[location]?.append(tool: tool)
}
@ -68,7 +68,7 @@ class Workspace: NSView {
// MARK: - Layout
extension Workspace {
private func relayout() {
fileprivate func relayout() {
// FIXME: I did not investigate why toggleButtons does not work correctly if we store all constraints in an array
// and remove them here by self.removeConstraints(${all constraints). The following seems to work...
self.subviews.forEach { $0.removeAllConstraints() }
@ -77,8 +77,8 @@ extension Workspace {
let mainView = self.mainView
self.addSubview(mainView)
mainView.autoSetDimension(.Width, toSize: self.config.mainViewMinimumSize.width, relation: .GreaterThanOrEqual)
mainView.autoSetDimension(.Height, toSize: self.config.mainViewMinimumSize.height, relation: .GreaterThanOrEqual)
mainView.autoSetDimension(.width, toSize: self.config.mainViewMinimumSize.width, relation: .greaterThanOrEqual)
mainView.autoSetDimension(.height, toSize: self.config.mainViewMinimumSize.height, relation: .greaterThanOrEqual)
guard self.isBarVisible else {
mainView.autoPinEdgesToSuperviewEdges()
@ -95,35 +95,35 @@ extension Workspace {
self.addSubview(bottomBar)
self.addSubview(leftBar)
topBar.autoPinEdgeToSuperviewEdge(.Top)
topBar.autoPinEdgeToSuperviewEdge(.Right)
topBar.autoPinEdgeToSuperviewEdge(.Left)
topBar.autoPinEdge(toSuperviewEdge: .top)
topBar.autoPinEdge(toSuperviewEdge: .right)
topBar.autoPinEdge(toSuperviewEdge: .left)
rightBar.autoPinEdge(.Top, toEdge: .Bottom, ofView: topBar)
rightBar.autoPinEdgeToSuperviewEdge(.Right)
rightBar.autoPinEdge(.Bottom, toEdge: .Top, ofView: bottomBar)
rightBar.autoPinEdge(.top, to: .bottom, of: topBar)
rightBar.autoPinEdge(toSuperviewEdge: .right)
rightBar.autoPinEdge(.bottom, to: .top, of: bottomBar)
bottomBar.autoPinEdgeToSuperviewEdge(.Right)
bottomBar.autoPinEdgeToSuperviewEdge(.Bottom)
bottomBar.autoPinEdgeToSuperviewEdge(.Left)
bottomBar.autoPinEdge(toSuperviewEdge: .right)
bottomBar.autoPinEdge(toSuperviewEdge: .bottom)
bottomBar.autoPinEdge(toSuperviewEdge: .left)
leftBar.autoPinEdge(.Top, toEdge: .Bottom, ofView: topBar)
leftBar.autoPinEdgeToSuperviewEdge(.Left)
leftBar.autoPinEdge(.Bottom, toEdge: .Top, ofView: bottomBar)
leftBar.autoPinEdge(.top, to: .bottom, of: topBar)
leftBar.autoPinEdge(toSuperviewEdge: .left)
leftBar.autoPinEdge(.bottom, to: .top, of: bottomBar)
NSLayoutConstraint.autoSetPriority(NSLayoutPriorityDragThatCannotResizeWindow) {
topBar.dimensionConstraint = topBar.autoSetDimension(.Height, toSize: 50)
rightBar.dimensionConstraint = rightBar.autoSetDimension(.Width, toSize: 50)
bottomBar.dimensionConstraint = bottomBar.autoSetDimension(.Height, toSize: 50)
leftBar.dimensionConstraint = leftBar.autoSetDimension(.Width, toSize: 50)
topBar.dimensionConstraint = topBar.autoSetDimension(.height, toSize: 50)
rightBar.dimensionConstraint = rightBar.autoSetDimension(.width, toSize: 50)
bottomBar.dimensionConstraint = bottomBar.autoSetDimension(.height, toSize: 50)
leftBar.dimensionConstraint = leftBar.autoSetDimension(.width, toSize: 50)
}
self.bars.values.forEach { $0.relayout() }
mainView.autoPinEdge(.Top, toEdge: .Bottom, ofView: topBar)
mainView.autoPinEdge(.Right, toEdge: .Left, ofView: rightBar)
mainView.autoPinEdge(.Bottom, toEdge: .Top, ofView: bottomBar)
mainView.autoPinEdge(.Left, toEdge: .Right, ofView: leftBar)
mainView.autoPinEdge(.top, to: .bottom, of: topBar)
mainView.autoPinEdge(.right, to: .left, of: rightBar)
mainView.autoPinEdge(.bottom, to: .top, of: bottomBar)
mainView.autoPinEdge(.left, to: .right, of: leftBar)
self.needsDisplay = true
}

View File

@ -8,16 +8,16 @@ import PureLayout
class WorkspaceBar: NSView, WorkspaceToolDelegate {
static private let separatorColor = NSColor.controlShadowColor()
static private let separatorThickness = CGFloat(1)
static fileprivate let separatorColor = NSColor.controlShadowColor
static fileprivate let separatorThickness = CGFloat(1)
private var tools = [WorkspaceTool]()
private weak var selectedTool: WorkspaceTool?
fileprivate var tools = [WorkspaceTool]()
fileprivate weak var selectedTool: WorkspaceTool?
private var isMouseDownOngoing = false
private var dragIncrement = CGFloat(1)
fileprivate var isMouseDownOngoing = false
fileprivate var dragIncrement = CGFloat(1)
private var layoutConstraints = [NSLayoutConstraint]()
fileprivate var layoutConstraints = [NSLayoutConstraint]()
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
@ -39,7 +39,7 @@ class WorkspaceBar: NSView, WorkspaceToolDelegate {
super.translatesAutoresizingMaskIntoConstraints = false
self.wantsLayer = true
self.layer!.backgroundColor = NSColor.windowBackgroundColor().CGColor
self.layer!.backgroundColor = NSColor.windowBackgroundColor.cgColor
}
func relayout() {
@ -47,7 +47,7 @@ class WorkspaceBar: NSView, WorkspaceToolDelegate {
self.removeAllSubviews()
if self.isEmpty() {
self.set(dimension: 0)
self.set(0)
return
}
@ -57,31 +57,31 @@ class WorkspaceBar: NSView, WorkspaceToolDelegate {
if self.isOpen() {
let curTool = self.selectedTool!
self.layout(tool: curTool)
self.layout(curTool)
let newDimension = self.barDimension(withToolDimension: curTool.dimension)
self.set(dimension: newDimension)
self.set(newDimension)
} else {
self.set(dimension: self.barDimensionWithButtonsWithoutTool())
self.set(self.barDimensionWithButtonsWithoutTool())
}
} else {
if self.isOpen() {
let curTool = self.selectedTool!
self.layoutWithoutButtons(tool: curTool)
self.layoutWithoutButtons(curTool)
let newDimension = self.barDimensionWithoutButtons(withToolDimension: curTool.dimension)
self.set(dimension: newDimension)
self.set(newDimension)
} else {
self.set(dimension: 0)
self.set(0)
}
}
self.needsDisplay = true
}
func append(tool tool: WorkspaceTool) {
func append(tool: WorkspaceTool) {
tool.delegate = self
tool.location = self.location
tools.append(tool)
@ -98,8 +98,8 @@ class WorkspaceBar: NSView, WorkspaceToolDelegate {
// MARK: - NSView
extension WorkspaceBar {
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
if self.isButtonVisible {
self.drawInnerSeparator(dirtyRect)
@ -110,7 +110,7 @@ extension WorkspaceBar {
}
}
override func mouseDown(event: NSEvent) {
override func mouseDown(with event: NSEvent) {
guard self.isOpen() else {
return
}
@ -119,11 +119,11 @@ extension WorkspaceBar {
return
}
let initialMouseLoc = self.convertPoint(event.locationInWindow, fromView: nil)
let mouseInResizeRect = NSMouseInRect(initialMouseLoc, self.resizeRect(), self.flipped)
let initialMouseLoc = self.convert(event.locationInWindow, from: nil)
let mouseInResizeRect = NSMouseInRect(initialMouseLoc, self.resizeRect(), self.isFlipped)
guard mouseInResizeRect && event.type == .LeftMouseDown else {
super.mouseDown(event)
guard mouseInResizeRect && event.type == .leftMouseDown else {
super.mouseDown(with: event)
return
}
@ -133,14 +133,14 @@ extension WorkspaceBar {
var dragged = false
var curEvent = event
let nextEventMask: NSEventMask = [
NSEventMask.LeftMouseDraggedMask,
NSEventMask.LeftMouseDownMask,
NSEventMask.LeftMouseUpMask
NSEventMask.leftMouseDragged,
NSEventMask.leftMouseDown,
NSEventMask.leftMouseUp
]
while curEvent.type != .LeftMouseUp {
let nextEvent = NSApp.nextEventMatchingMask(Int(nextEventMask.rawValue),
untilDate: NSDate.distantFuture(),
inMode: NSEventTrackingRunLoopMode,
while curEvent.type != .leftMouseUp {
let nextEvent = NSApp.nextEvent(matching: NSEventMask(rawValue: UInt64(Int(nextEventMask.rawValue))),
until: Date.distantFuture,
inMode: RunLoopMode.eventTrackingRunLoopMode,
dequeue: true)
guard nextEvent != nil else {
break
@ -148,23 +148,23 @@ extension WorkspaceBar {
curEvent = nextEvent!
guard curEvent.type == .LeftMouseDragged else {
guard curEvent.type == .leftMouseDragged else {
break
}
let curMouseLoc = self.convertPoint(curEvent.locationInWindow, fromView: nil)
let curMouseLoc = self.convert(curEvent.locationInWindow, from: nil)
let distance = sq(initialMouseLoc.x - curMouseLoc.x) + sq(initialMouseLoc.y - curMouseLoc.y)
guard dragged || distance >= 1 else {
continue
}
let locInSuperview = self.superview!.convertPoint(curEvent.locationInWindow, fromView: nil)
let locInSuperview = self.superview!.convert(curEvent.locationInWindow, from: nil)
let newDimension = self.newDimension(forLocationInSuperview: locInSuperview)
self.set(dimension: newDimension)
self.set(newDimension)
self.window?.invalidateCursorRectsForView(self)
self.window?.invalidateCursorRects(for: self)
dragged = true
}
@ -180,13 +180,13 @@ extension WorkspaceBar {
switch self.location {
case .top, .bottom:
self.addCursorRect(self.resizeRect(), cursor: NSCursor.resizeUpDownCursor())
self.addCursorRect(self.resizeRect(), cursor: NSCursor.resizeUpDown())
case .right, .left:
self.addCursorRect(self.resizeRect(), cursor: NSCursor.resizeLeftRightCursor())
self.addCursorRect(self.resizeRect(), cursor: NSCursor.resizeLeftRight())
}
}
private func drawInnerSeparator(dirtyRect: NSRect) {
fileprivate func drawInnerSeparator(_ dirtyRect: NSRect) {
WorkspaceBar.separatorColor.set()
let innerLineRect = self.innerSeparatorRect()
@ -195,7 +195,7 @@ extension WorkspaceBar {
}
}
private func drawOuterSeparator(dirtyRect: NSRect) {
fileprivate func drawOuterSeparator(_ dirtyRect: NSRect) {
WorkspaceBar.separatorColor.set()
let outerLineRect = self.outerSeparatorRect()
@ -204,7 +204,7 @@ extension WorkspaceBar {
}
}
private func buttonSize() -> CGSize {
fileprivate func buttonSize() -> CGSize {
if self.isEmpty() {
return CGSize.zero
}
@ -212,7 +212,7 @@ extension WorkspaceBar {
return self.tools.first!.button.intrinsicContentSize
}
private func innerSeparatorRect() -> CGRect {
fileprivate func innerSeparatorRect() -> CGRect {
let bounds = self.bounds
let thickness = WorkspaceBar.separatorThickness
let bar = self.buttonSize()
@ -229,12 +229,12 @@ extension WorkspaceBar {
}
}
private func newDimension(forLocationInSuperview locInSuperview: CGPoint) -> CGFloat {
fileprivate func newDimension(forLocationInSuperview locInSuperview: CGPoint) -> CGFloat {
let dimension = self.dimension(forLocationInSuperview: locInSuperview)
return self.dragIncrement * floor(dimension / self.dragIncrement)
}
private func dimension(forLocationInSuperview locInSuperview: CGPoint) -> CGFloat {
fileprivate func dimension(forLocationInSuperview locInSuperview: CGPoint) -> CGFloat {
let superviewBounds = self.superview!.bounds
switch self.location {
@ -249,11 +249,11 @@ extension WorkspaceBar {
}
}
private func sq(number: CGFloat) -> CGFloat {
fileprivate func sq(_ number: CGFloat) -> CGFloat {
return number * number
}
private func outerSeparatorRect() -> CGRect {
fileprivate func outerSeparatorRect() -> CGRect {
let thickness = WorkspaceBar.separatorThickness
switch self.location {
@ -268,7 +268,7 @@ extension WorkspaceBar {
}
}
private func resizeRect() -> CGRect {
fileprivate func resizeRect() -> CGRect {
let separatorRect = self.outerSeparatorRect()
let clickDimension = CGFloat(4)
@ -284,7 +284,7 @@ extension WorkspaceBar {
}
}
private func set(dimension dimension: CGFloat) {
fileprivate func set(_ dimension: CGFloat) {
self.dimensionConstraint.constant = dimension
let toolDimension = self.toolDimension(fromBarDimension: dimension)
@ -297,64 +297,64 @@ extension WorkspaceBar {
// MARK: - Layout
extension WorkspaceBar {
private func isEmpty() -> Bool {
fileprivate func isEmpty() -> Bool {
return self.tools.isEmpty
}
private func hasTools() -> Bool {
fileprivate func hasTools() -> Bool {
return !self.isEmpty()
}
private func isOpen() -> Bool {
fileprivate func isOpen() -> Bool {
return self.selectedTool != nil
}
private func layoutWithoutButtons(tool tool: WorkspaceTool) {
fileprivate func layoutWithoutButtons(_ tool: WorkspaceTool) {
let view = tool.view
let thickness = WorkspaceBar.separatorThickness
self.addSubview(view)
switch self.location {
case .top:
self.layoutConstraints.appendContentsOf([
view.autoPinEdgeToSuperviewEdge(.Top),
view.autoPinEdgeToSuperviewEdge(.Right),
view.autoPinEdgeToSuperviewEdge(.Bottom, withInset: thickness),
view.autoPinEdgeToSuperviewEdge(.Left),
self.layoutConstraints.append(contentsOf: [
view.autoPinEdge(toSuperviewEdge: .top),
view.autoPinEdge(toSuperviewEdge: .right),
view.autoPinEdge(toSuperviewEdge: .bottom, withInset: thickness),
view.autoPinEdge(toSuperviewEdge: .left),
view.autoSetDimension(.Height, toSize: tool.minimumDimension, relation: .GreaterThanOrEqual)
view.autoSetDimension(.height, toSize: tool.minimumDimension, relation: .greaterThanOrEqual)
])
case .right:
self.layoutConstraints.appendContentsOf([
view.autoPinEdgeToSuperviewEdge(.Top),
view.autoPinEdgeToSuperviewEdge(.Right),
view.autoPinEdgeToSuperviewEdge(.Bottom),
view.autoPinEdgeToSuperviewEdge(.Left, withInset: thickness),
self.layoutConstraints.append(contentsOf: [
view.autoPinEdge(toSuperviewEdge: .top),
view.autoPinEdge(toSuperviewEdge: .right),
view.autoPinEdge(toSuperviewEdge: .bottom),
view.autoPinEdge(toSuperviewEdge: .left, withInset: thickness),
view.autoSetDimension(.Width, toSize: tool.minimumDimension, relation: .GreaterThanOrEqual)
view.autoSetDimension(.width, toSize: tool.minimumDimension, relation: .greaterThanOrEqual)
])
case .bottom:
self.layoutConstraints.appendContentsOf([
view.autoPinEdgeToSuperviewEdge(.Top, withInset: thickness),
view.autoPinEdgeToSuperviewEdge(.Right),
view.autoPinEdgeToSuperviewEdge(.Bottom),
view.autoPinEdgeToSuperviewEdge(.Left),
self.layoutConstraints.append(contentsOf: [
view.autoPinEdge(toSuperviewEdge: .top, withInset: thickness),
view.autoPinEdge(toSuperviewEdge: .right),
view.autoPinEdge(toSuperviewEdge: .bottom),
view.autoPinEdge(toSuperviewEdge: .left),
view.autoSetDimension(.Height, toSize: tool.minimumDimension, relation: .GreaterThanOrEqual)
view.autoSetDimension(.height, toSize: tool.minimumDimension, relation: .greaterThanOrEqual)
])
case .left:
self.layoutConstraints.appendContentsOf([
view.autoPinEdgeToSuperviewEdge(.Top),
view.autoPinEdgeToSuperviewEdge(.Right, withInset: thickness),
view.autoPinEdgeToSuperviewEdge(.Bottom),
view.autoPinEdgeToSuperviewEdge(.Left),
self.layoutConstraints.append(contentsOf: [
view.autoPinEdge(toSuperviewEdge: .top),
view.autoPinEdge(toSuperviewEdge: .right, withInset: thickness),
view.autoPinEdge(toSuperviewEdge: .bottom),
view.autoPinEdge(toSuperviewEdge: .left),
view.autoSetDimension(.Width, toSize: tool.minimumDimension, relation: .GreaterThanOrEqual)
view.autoSetDimension(.width, toSize: tool.minimumDimension, relation: .greaterThanOrEqual)
])
}
}
private func layout(tool tool: WorkspaceTool) {
fileprivate func layout(_ tool: WorkspaceTool) {
let view = tool.view
let button = tool.button
let thickness = WorkspaceBar.separatorThickness
@ -363,45 +363,45 @@ extension WorkspaceBar {
switch self.location {
case .top:
self.layoutConstraints.appendContentsOf([
view.autoPinEdge(.Top, toEdge: .Bottom, ofView: button, withOffset: thickness),
view.autoPinEdgeToSuperviewEdge(.Right),
view.autoPinEdgeToSuperviewEdge(.Bottom, withInset: thickness),
view.autoPinEdgeToSuperviewEdge(.Left),
self.layoutConstraints.append(contentsOf: [
view.autoPinEdge(.top, to: .bottom, of: button, withOffset: thickness),
view.autoPinEdge(toSuperviewEdge: .right),
view.autoPinEdge(toSuperviewEdge: .bottom, withInset: thickness),
view.autoPinEdge(toSuperviewEdge: .left),
view.autoSetDimension(.Height, toSize: tool.minimumDimension, relation: .GreaterThanOrEqual)
view.autoSetDimension(.height, toSize: tool.minimumDimension, relation: .greaterThanOrEqual)
])
case .right:
self.layoutConstraints.appendContentsOf([
view.autoPinEdgeToSuperviewEdge(.Top),
view.autoPinEdge(.Right, toEdge: .Left, ofView: button, withOffset: -thickness), // Offset is count l -> r,
view.autoPinEdgeToSuperviewEdge(.Bottom),
view.autoPinEdgeToSuperviewEdge(.Left, withInset: thickness),
self.layoutConstraints.append(contentsOf: [
view.autoPinEdge(toSuperviewEdge: .top),
view.autoPinEdge(.right, to: .left, of: button, withOffset: -thickness), // Offset is count l -> r,
view.autoPinEdge(toSuperviewEdge: .bottom),
view.autoPinEdge(toSuperviewEdge: .left, withInset: thickness),
view.autoSetDimension(.Width, toSize: tool.minimumDimension, relation: .GreaterThanOrEqual)
view.autoSetDimension(.width, toSize: tool.minimumDimension, relation: .greaterThanOrEqual)
])
case .bottom:
self.layoutConstraints.appendContentsOf([
view.autoPinEdgeToSuperviewEdge(.Top, withInset: thickness),
view.autoPinEdgeToSuperviewEdge(.Right),
view.autoPinEdge(.Bottom, toEdge: .Top, ofView: button, withOffset: -thickness), // Offset is count t -> b,
view.autoPinEdgeToSuperviewEdge(.Left),
self.layoutConstraints.append(contentsOf: [
view.autoPinEdge(toSuperviewEdge: .top, withInset: thickness),
view.autoPinEdge(toSuperviewEdge: .right),
view.autoPinEdge(.bottom, to: .top, of: button, withOffset: -thickness), // Offset is count t -> b,
view.autoPinEdge(toSuperviewEdge: .left),
view.autoSetDimension(.Height, toSize: tool.minimumDimension, relation: .GreaterThanOrEqual)
view.autoSetDimension(.height, toSize: tool.minimumDimension, relation: .greaterThanOrEqual)
])
case .left:
self.layoutConstraints.appendContentsOf([
view.autoPinEdgeToSuperviewEdge(.Top),
view.autoPinEdgeToSuperviewEdge(.Right, withInset: thickness),
view.autoPinEdgeToSuperviewEdge(.Bottom),
view.autoPinEdge(.Left, toEdge: .Right, ofView: button, withOffset: thickness),
self.layoutConstraints.append(contentsOf: [
view.autoPinEdge(toSuperviewEdge: .top),
view.autoPinEdge(toSuperviewEdge: .right, withInset: thickness),
view.autoPinEdge(toSuperviewEdge: .bottom),
view.autoPinEdge(.left, to: .right, of: button, withOffset: thickness),
view.autoSetDimension(.Width, toSize: tool.minimumDimension, relation: .GreaterThanOrEqual)
view.autoSetDimension(.width, toSize: tool.minimumDimension, relation: .greaterThanOrEqual)
])
}
}
private func layoutButtons() {
fileprivate func layoutButtons() {
guard let firstTool = self.tools.first else {
return
}
@ -413,24 +413,24 @@ extension WorkspaceBar {
let firstButton = firstTool.button
switch self.location {
case .top:
self.layoutConstraints.appendContentsOf([
firstButton.autoPinEdgeToSuperviewEdge(.Top),
firstButton.autoPinEdgeToSuperviewEdge(.Left),
self.layoutConstraints.append(contentsOf: [
firstButton.autoPinEdge(toSuperviewEdge: .top),
firstButton.autoPinEdge(toSuperviewEdge: .left),
])
case .right:
self.layoutConstraints.appendContentsOf([
firstButton.autoPinEdgeToSuperviewEdge(.Top),
firstButton.autoPinEdgeToSuperviewEdge(.Right),
self.layoutConstraints.append(contentsOf: [
firstButton.autoPinEdge(toSuperviewEdge: .top),
firstButton.autoPinEdge(toSuperviewEdge: .right),
])
case .bottom:
self.layoutConstraints.appendContentsOf([
firstButton.autoPinEdgeToSuperviewEdge(.Left),
firstButton.autoPinEdgeToSuperviewEdge(.Bottom),
self.layoutConstraints.append(contentsOf: [
firstButton.autoPinEdge(toSuperviewEdge: .left),
firstButton.autoPinEdge(toSuperviewEdge: .bottom),
])
case .left:
self.layoutConstraints.appendContentsOf([
firstButton.autoPinEdgeToSuperviewEdge(.Top),
firstButton.autoPinEdgeToSuperviewEdge(.Left),
self.layoutConstraints.append(contentsOf: [
firstButton.autoPinEdge(toSuperviewEdge: .top),
firstButton.autoPinEdge(toSuperviewEdge: .left),
])
}
@ -438,24 +438,24 @@ extension WorkspaceBar {
for button in self.tools[1..<self.tools.count].map({ $0.button }) {
switch self.location {
case .top:
self.layoutConstraints.appendContentsOf([
button.autoPinEdgeToSuperviewEdge(.Top),
button.autoPinEdge(.Left, toEdge: .Right, ofView: lastButton),
self.layoutConstraints.append(contentsOf: [
button.autoPinEdge(toSuperviewEdge: .top),
button.autoPinEdge(.left, to: .right, of: lastButton),
])
case .right:
self.layoutConstraints.appendContentsOf([
button.autoPinEdge(.Top, toEdge: .Bottom, ofView: lastButton),
button.autoPinEdgeToSuperviewEdge(.Right),
self.layoutConstraints.append(contentsOf: [
button.autoPinEdge(.top, to: .bottom, of: lastButton),
button.autoPinEdge(toSuperviewEdge: .right),
])
case .bottom:
self.layoutConstraints.appendContentsOf([
button.autoPinEdge(.Left, toEdge: .Right, ofView: lastButton),
button.autoPinEdgeToSuperviewEdge(.Bottom),
self.layoutConstraints.append(contentsOf: [
button.autoPinEdge(.left, to: .right, of: lastButton),
button.autoPinEdge(toSuperviewEdge: .bottom),
])
case .left:
self.layoutConstraints.appendContentsOf([
button.autoPinEdge(.Top, toEdge: .Bottom, ofView: lastButton),
button.autoPinEdgeToSuperviewEdge(.Left),
self.layoutConstraints.append(contentsOf: [
button.autoPinEdge(.top, to: .bottom, of: lastButton),
button.autoPinEdge(toSuperviewEdge: .left),
])
}
@ -463,7 +463,7 @@ extension WorkspaceBar {
}
}
private func barDimensionWithButtonsWithoutTool() -> CGFloat {
fileprivate func barDimensionWithButtonsWithoutTool() -> CGFloat {
switch self.location {
case .top, .bottom:
return self.buttonSize().height + WorkspaceBar.separatorThickness
@ -472,15 +472,15 @@ extension WorkspaceBar {
}
}
private func barDimensionWithoutButtons(withToolDimension toolDimension: CGFloat) -> CGFloat {
fileprivate func barDimensionWithoutButtons(withToolDimension toolDimension: CGFloat) -> CGFloat {
return toolDimension + WorkspaceBar.separatorThickness
}
private func barDimension(withToolDimension toolDimension: CGFloat) -> CGFloat {
fileprivate func barDimension(withToolDimension toolDimension: CGFloat) -> CGFloat {
return self.barDimensionWithButtonsWithoutTool() + toolDimension + WorkspaceBar.separatorThickness
}
private func toolDimension(fromBarDimension barDimension: CGFloat) -> CGFloat {
fileprivate func toolDimension(fromBarDimension barDimension: CGFloat) -> CGFloat {
if self.isButtonVisible {
return barDimension - WorkspaceBar.separatorThickness - barDimensionWithButtonsWithoutTool()
}
@ -492,7 +492,7 @@ extension WorkspaceBar {
// MARK: - WorkspaceToolDelegate
extension WorkspaceBar {
func toggle(tool tool: WorkspaceTool) {
func toggle(_ tool: WorkspaceTool) {
if self.isOpen() {
let curTool = self.selectedTool!
if curTool === tool {

View File

@ -7,7 +7,7 @@ import Cocoa
protocol WorkspaceToolDelegate: class {
func toggle(tool tool: WorkspaceTool)
func toggle(_ tool: WorkspaceTool)
}
class WorkspaceTool {
@ -46,7 +46,7 @@ class WorkspaceTool {
}
func toggle() {
self.delegate?.toggle(tool: self)
self.delegate?.toggle(self)
self.isSelected = !self.isSelected
}
}

View File

@ -7,10 +7,10 @@ import Cocoa
class WorkspaceToolButton: NSView {
static private let titlePadding = CGSize(width: 8, height: 2)
static fileprivate let titlePadding = CGSize(width: 8, height: 2)
private let title: NSAttributedString
private var trackingArea = NSTrackingArea()
fileprivate let title: NSAttributedString
fileprivate var trackingArea = NSTrackingArea()
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
@ -26,7 +26,7 @@ class WorkspaceToolButton: NSView {
init(title: String) {
self.title = NSAttributedString(string: title, attributes: [
NSFontAttributeName: NSFont.systemFontOfSize(11)
NSFontAttributeName: NSFont.systemFont(ofSize: 11)
])
super.init(frame: CGRect.zero)
@ -36,11 +36,11 @@ class WorkspaceToolButton: NSView {
}
func highlight() {
self.layer?.backgroundColor = NSColor.controlShadowColor().CGColor
self.layer?.backgroundColor = NSColor.controlShadowColor.cgColor
}
func dehighlight() {
self.layer?.backgroundColor = NSColor.clearColor().CGColor
self.layer?.backgroundColor = NSColor.clear.cgColor
}
}
@ -59,13 +59,13 @@ extension WorkspaceToolButton {
}
}
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
let padding = WorkspaceToolButton.titlePadding
switch self.location {
case .top, .bottom:
self.title.drawAtPoint(CGPoint(x: padding.width, y: padding.height))
self.title.draw(at: CGPoint(x: padding.width, y: padding.height))
case .right:
self.title.draw(at: CGPoint(x: padding.height, y: self.bounds.height - padding.width), angle: -CGFloat(M_PI_2))
case .left:
@ -77,7 +77,7 @@ extension WorkspaceToolButton {
self.removeTrackingArea(self.trackingArea)
self.trackingArea = NSTrackingArea(rect: self.bounds,
options: [.MouseEnteredAndExited, .ActiveInActiveApp],
options: [.mouseEnteredAndExited, .activeInActiveApp],
owner: self,
userInfo: nil)
self.addTrackingArea(self.trackingArea)
@ -85,11 +85,11 @@ extension WorkspaceToolButton {
super.updateTrackingAreas()
}
override func mouseDown(event: NSEvent) {
override func mouseDown(with event: NSEvent) {
self.tool?.toggle()
}
override func mouseEntered(_: NSEvent) {
override func mouseEntered(with _: NSEvent) {
if self.isSelected {
return
}
@ -97,7 +97,7 @@ extension WorkspaceToolButton {
self.highlight()
}
override func mouseExited(_: NSEvent) {
override func mouseExited(with _: NSEvent) {
if self.isSelected {
return
}

View File

@ -8,17 +8,17 @@ import Nimble
class FileUtilsTest: XCTestCase {
var fileUtilsRsrcUrl = NSURL()
var a1Dir = NSURL()
var fileUtilsRsrcUrl = URL()
var a1Dir = URL()
override func setUp() {
fileUtilsRsrcUrl = NSBundle.init(forClass: self.dynamicType).URLForResource("FileUtilsTest", withExtension: "")!
a1Dir = fileUtilsRsrcUrl.URLByAppendingPathComponent("a1")
fileUtilsRsrcUrl = Bundle.init(for: type(of: self)).url(forResource: "FileUtilsTest", withExtension: "")!
a1Dir = fileUtilsRsrcUrl.appendingPathComponent("a1")
}
func testCommonParentOneDirUrl() {
let urls = [
fileUtilsRsrcUrl.URLByAppendingPathComponent("a1"),
fileUtilsRsrcUrl.appendingPathComponent("a1"),
]
expect(FileUtils.commonParent(ofUrls: urls)).to(equal(a1Dir))
@ -26,20 +26,20 @@ class FileUtilsTest: XCTestCase {
func testCommonParentOneFileUrl() {
let urls = [
fileUtilsRsrcUrl.URLByAppendingPathComponent("a1/a1-file1"),
fileUtilsRsrcUrl.appendingPathComponent("a1/a1-file1"),
]
expect(FileUtils.commonParent(ofUrls: urls)).to(equal(a1Dir))
}
func testCommonParentEmptyParams() {
expect(FileUtils.commonParent(ofUrls: [])).to(equal(NSURL(fileURLWithPath: "/", isDirectory: true)))
expect(FileUtils.commonParent(ofUrls: []) as URL).to(equal(URL(fileURLWithPath: "/", isDirectory: true)))
}
func testCommonParent1() {
let urls = [
fileUtilsRsrcUrl.URLByAppendingPathComponent("a1"),
fileUtilsRsrcUrl.URLByAppendingPathComponent("a1/a1-file1"),
fileUtilsRsrcUrl.appendingPathComponent("a1"),
fileUtilsRsrcUrl.appendingPathComponent("a1/a1-file1"),
]
expect(FileUtils.commonParent(ofUrls: urls)).to(equal(a1Dir))
@ -47,9 +47,9 @@ class FileUtilsTest: XCTestCase {
func testCommonParent2() {
let urls = [
fileUtilsRsrcUrl.URLByAppendingPathComponent("a1"),
fileUtilsRsrcUrl.URLByAppendingPathComponent("a1/a1-file1"),
fileUtilsRsrcUrl.URLByAppendingPathComponent("a1/a2/a1-a2-file1"),
fileUtilsRsrcUrl.appendingPathComponent("a1"),
fileUtilsRsrcUrl.appendingPathComponent("a1/a1-file1"),
fileUtilsRsrcUrl.appendingPathComponent("a1/a2/a1-a2-file1"),
]
expect(FileUtils.commonParent(ofUrls: urls)).to(equal(a1Dir))
@ -57,10 +57,10 @@ class FileUtilsTest: XCTestCase {
func testCommonParent3() {
let urls = [
fileUtilsRsrcUrl.URLByAppendingPathComponent("a1"),
fileUtilsRsrcUrl.URLByAppendingPathComponent("a1/a1-file1"),
fileUtilsRsrcUrl.URLByAppendingPathComponent("a1/a2/a1-a2-file1"),
fileUtilsRsrcUrl.URLByAppendingPathComponent("b1/b1-file1"),
fileUtilsRsrcUrl.appendingPathComponent("a1"),
fileUtilsRsrcUrl.appendingPathComponent("a1/a1-file1"),
fileUtilsRsrcUrl.appendingPathComponent("a1/a2/a1-a2-file1"),
fileUtilsRsrcUrl.appendingPathComponent("b1/b1-file1"),
]
expect(FileUtils.commonParent(ofUrls: urls)).to(equal(fileUtilsRsrcUrl))
@ -68,10 +68,10 @@ class FileUtilsTest: XCTestCase {
func testCommonParent4() {
let urls = [
fileUtilsRsrcUrl.URLByAppendingPathComponent("a1"),
fileUtilsRsrcUrl.URLByAppendingPathComponent("a1/a1-file1"),
fileUtilsRsrcUrl.URLByAppendingPathComponent("a1/a2/a1-a2-file1"),
fileUtilsRsrcUrl.URLByAppendingPathComponent("b1"),
fileUtilsRsrcUrl.appendingPathComponent("a1"),
fileUtilsRsrcUrl.appendingPathComponent("a1/a1-file1"),
fileUtilsRsrcUrl.appendingPathComponent("a1/a2/a1-a2-file1"),
fileUtilsRsrcUrl.appendingPathComponent("b1"),
]
expect(FileUtils.commonParent(ofUrls: urls)).to(equal(fileUtilsRsrcUrl))
@ -79,9 +79,9 @@ class FileUtilsTest: XCTestCase {
func testCommonParent5() {
let urls = [
fileUtilsRsrcUrl.URLByAppendingPathComponent("a1/a1-file1"),
fileUtilsRsrcUrl.URLByAppendingPathComponent("a1/a2/a1-a2-file1"),
fileUtilsRsrcUrl.URLByAppendingPathComponent("a1/a2"),
fileUtilsRsrcUrl.appendingPathComponent("a1/a1-file1"),
fileUtilsRsrcUrl.appendingPathComponent("a1/a2/a1-a2-file1"),
fileUtilsRsrcUrl.appendingPathComponent("a1/a2"),
]
expect(FileUtils.commonParent(ofUrls: urls)).to(equal(a1Dir))

View File

@ -9,11 +9,11 @@ import Nimble
class ScorerTest: XCTestCase {
func testScore1() {
let pattern = "sw/nvv".stringByReplacingOccurrencesOfString("/", withString: "")
let pattern = "sw/nvv".replacingOccurrences(of: "/", with: "")
let targets = [
"SwiftNeoVim/NeoVimView.swift",
"build/Release/NeoVimServer.dSYM/Contents/Resources/DWARF/NeoVimServer",
].map { $0.stringByReplacingOccurrencesOfString("/", withString: "") }
].map { $0.replacingOccurrences(of: "/", with: "") }
expect(Scorer.score(targets[0], pattern: pattern)).to(beGreaterThan(Scorer.score(targets[1], pattern: pattern)))
}