mirror of
https://github.com/qvacua/vimr.git
synced 2024-12-30 09:12:09 +03:00
Merge branch 'master' into update-neovim
This commit is contained in:
commit
339bd0ce3a
@ -1,6 +1,6 @@
|
||||
--swiftversion 5.3
|
||||
|
||||
--exclude Carthage,third-party,**/*.generated.swift
|
||||
--exclude Carthage,third-party,**/*.generated.swift,**/*.template.swift
|
||||
|
||||
--indent 2
|
||||
--maxwidth 100
|
||||
|
@ -143,7 +143,7 @@ class ArraySliceTest: XCTestCase {
|
||||
expect(grouped).to(equal(
|
||||
[
|
||||
1...1,
|
||||
2...2
|
||||
2...2,
|
||||
]
|
||||
))
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public final class GitUtils {
|
||||
public enum GitUtils {
|
||||
static func globalGitignoreFileUrl() -> URL? {
|
||||
guard let path = shellCommandOutput(
|
||||
"git config --get core.excludesFile",
|
||||
|
@ -26,7 +26,7 @@ final class CellAttributesCollection {
|
||||
|
||||
func attributes(of id: Int, withDefaults defaults: CellAttributes) -> CellAttributes? {
|
||||
if id == Self.markedAttributesId {
|
||||
var attr = defaultAttributes
|
||||
var attr = self.defaultAttributes
|
||||
attr.fontTrait.formUnion(.underline)
|
||||
return attr
|
||||
}
|
||||
|
@ -21,8 +21,7 @@ private struct SizedFontTrait: Hashable {
|
||||
|
||||
extension FontTrait: Hashable {}
|
||||
|
||||
final class FontUtils {
|
||||
|
||||
enum FontUtils {
|
||||
static func fontHeight(of font: NSFont) -> CGFloat {
|
||||
if let cached = fontHeightCache.valueForKey(font) { return cached }
|
||||
|
||||
|
@ -37,6 +37,7 @@ final class KeyUtils {
|
||||
|
||||
return key
|
||||
}
|
||||
|
||||
static func isHalfWidth(char: Character) -> Bool {
|
||||
// https://stackoverflow.com/questions/13505075/analyzing-full-width-or-half-width-character-in-java?noredirect=1&lq=1 // swiftlint:disable:this all
|
||||
switch char {
|
||||
|
@ -6,9 +6,9 @@
|
||||
import Cocoa
|
||||
import MessagePack
|
||||
import PureLayout
|
||||
import RxNeovim
|
||||
import RxPack
|
||||
import RxSwift
|
||||
import RxNeovim
|
||||
import SpriteKit
|
||||
|
||||
public extension NvimView {
|
||||
|
@ -204,7 +204,8 @@ public extension NvimView {
|
||||
|
||||
func _unmarkText() {
|
||||
guard self.hasMarkedText() else { return }
|
||||
// wait inserted text gui update event, so hanji in korean get right previous string and can popup candidate window
|
||||
// wait inserted text gui update event, so hanji in korean get right previous string and can
|
||||
// popup candidate window
|
||||
DispatchQueue.main.async { [self] in
|
||||
if let markedInfo = self.ugrid.markedInfo {
|
||||
self.ugrid.markedInfo = nil
|
||||
|
@ -6,44 +6,44 @@
|
||||
import Cocoa
|
||||
import RxSwift
|
||||
|
||||
extension NvimView {
|
||||
override public func mouseDown(with event: NSEvent) {
|
||||
public extension NvimView {
|
||||
override func mouseDown(with event: NSEvent) {
|
||||
self.mouse(event: event, vimName: "LeftMouse")
|
||||
}
|
||||
|
||||
override public func mouseUp(with event: NSEvent) {
|
||||
override func mouseUp(with event: NSEvent) {
|
||||
self.mouse(event: event, vimName: "LeftRelease")
|
||||
}
|
||||
|
||||
override public func mouseDragged(with event: NSEvent) {
|
||||
override func mouseDragged(with event: NSEvent) {
|
||||
self.mouse(event: event, vimName: "LeftDrag")
|
||||
}
|
||||
|
||||
override public func rightMouseDown(with event: NSEvent) {
|
||||
override func rightMouseDown(with event: NSEvent) {
|
||||
self.mouse(event: event, vimName: "RightMouse")
|
||||
}
|
||||
|
||||
override public func rightMouseUp(with event: NSEvent) {
|
||||
override func rightMouseUp(with event: NSEvent) {
|
||||
self.mouse(event: event, vimName: "RightRelease")
|
||||
}
|
||||
|
||||
override public func rightMouseDragged(with event: NSEvent) {
|
||||
override func rightMouseDragged(with event: NSEvent) {
|
||||
self.mouse(event: event, vimName: "RightDrag")
|
||||
}
|
||||
|
||||
override public func otherMouseUp(with event: NSEvent) {
|
||||
override func otherMouseUp(with event: NSEvent) {
|
||||
self.mouse(event: event, vimName: "MiddleMouse")
|
||||
}
|
||||
|
||||
override public func otherMouseDown(with event: NSEvent) {
|
||||
override func otherMouseDown(with event: NSEvent) {
|
||||
self.mouse(event: event, vimName: "MiddleRelease")
|
||||
}
|
||||
|
||||
override public func otherMouseDragged(with event: NSEvent) {
|
||||
override func otherMouseDragged(with event: NSEvent) {
|
||||
self.mouse(event: event, vimName: "MiddleDrag")
|
||||
}
|
||||
|
||||
override public func scrollWheel(with event: NSEvent) {
|
||||
override func scrollWheel(with event: NSEvent) {
|
||||
let (deltaX, deltaY) = (event.scrollingDeltaX, event.scrollingDeltaY)
|
||||
if deltaX == 0, deltaY == 0 { return }
|
||||
|
||||
@ -69,15 +69,15 @@ extension NvimView {
|
||||
}
|
||||
|
||||
if event.phase == .began {
|
||||
self.trackpadScrollDeltaX = 0
|
||||
self.trackpadScrollDeltaY = 0
|
||||
self.trackpadScrollDeltaX = 0
|
||||
self.trackpadScrollDeltaY = 0
|
||||
}
|
||||
|
||||
self.trackpadScrollDeltaX += deltaX
|
||||
self.trackpadScrollDeltaY += deltaY
|
||||
let (deltaCellX, deltaCellY) = (
|
||||
(self.trackpadScrollDeltaX / self.cellSize.width).rounded(.toNearestOrEven),
|
||||
(self.trackpadScrollDeltaY / self.cellSize.height).rounded(.toNearestOrEven)
|
||||
(self.trackpadScrollDeltaX / self.cellSize.width).rounded(.toNearestOrEven),
|
||||
(self.trackpadScrollDeltaY / self.cellSize.height).rounded(.toNearestOrEven)
|
||||
)
|
||||
self.trackpadScrollDeltaX.formRemainder(dividingBy: self.cellSize.width)
|
||||
self.trackpadScrollDeltaY.formRemainder(dividingBy: self.cellSize.height)
|
||||
@ -95,7 +95,7 @@ extension NvimView {
|
||||
.disposed(by: self.disposeBag)
|
||||
}
|
||||
|
||||
override public func magnify(with event: NSEvent) {
|
||||
override func magnify(with event: NSEvent) {
|
||||
let factor = 1 + event.magnification
|
||||
let pinchTargetScale = self.pinchTargetScale * factor
|
||||
let resultingFontSize = round(pinchTargetScale * self.font.pointSize)
|
||||
@ -123,7 +123,7 @@ extension NvimView {
|
||||
self.markForRenderWholeView()
|
||||
}
|
||||
|
||||
func position(at location: CGPoint) -> Position {
|
||||
internal func position(at location: CGPoint) -> Position {
|
||||
let row = Int((self.bounds.size.height - location.y - self.offset.y) / self.cellSize.height)
|
||||
let column = Int((location.x - self.offset.x) / self.cellSize.width)
|
||||
|
||||
|
@ -4,8 +4,8 @@
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
import RxPack
|
||||
import RxNeovim
|
||||
import RxPack
|
||||
|
||||
public extension NvimView {
|
||||
struct Buffer: Equatable {
|
||||
|
@ -5,9 +5,9 @@
|
||||
*/
|
||||
|
||||
import Cocoa
|
||||
import RxNeovim
|
||||
import RxPack
|
||||
import RxSwift
|
||||
import RxNeovim
|
||||
|
||||
extension NvimView: NSTouchBarDelegate, NSScrubberDataSource, NSScrubberDelegate {
|
||||
override public func makeTouchBar() -> NSTouchBar? {
|
||||
@ -66,11 +66,11 @@ extension NvimView: NSTouchBarDelegate, NSScrubberDataSource, NSScrubberDelegate
|
||||
.observe(on: MainScheduler.instance)
|
||||
.subscribe(onSuccess: { [weak self] in
|
||||
self?.tabsCache = $0
|
||||
|
||||
|
||||
guard let tabsControl = self?.getTabsControl() else { return }
|
||||
|
||||
|
||||
tabsControl.reloadData()
|
||||
|
||||
|
||||
let scrubberProportionalLayout = tabsControl.scrubberLayout as! NSScrubberProportionalLayout
|
||||
scrubberProportionalLayout.numberOfVisibleItems = tabsControl
|
||||
.numberOfItems > 0 ? tabsControl.numberOfItems : 1
|
||||
@ -87,9 +87,9 @@ extension NvimView: NSTouchBarDelegate, NSScrubberDataSource, NSScrubberDelegate
|
||||
.observe(on: MainScheduler.instance)
|
||||
.subscribe(onSuccess: { [weak self] in
|
||||
self?.tabsCache = $0
|
||||
|
||||
|
||||
guard let tabsControl = self?.getTabsControl() else { return }
|
||||
|
||||
|
||||
tabsControl.reloadData()
|
||||
tabsControl.selectedIndex = self?.selectedTabIndex() ?? tabsControl.selectedIndex
|
||||
}, onFailure: { error in
|
||||
|
@ -6,8 +6,8 @@
|
||||
import Cocoa
|
||||
import MessagePack
|
||||
import PureLayout
|
||||
import RxPack
|
||||
import RxNeovim
|
||||
import RxPack
|
||||
import Tabs
|
||||
|
||||
public extension NvimView {
|
||||
|
@ -137,8 +137,8 @@ final class UGrid: CustomStringConvertible, Codable {
|
||||
step = -1
|
||||
}
|
||||
var oldMarkedInfo: MarkedInfo?
|
||||
if let row = self.markedInfo?.position.row, region.top <= row && row <= region.bottom {
|
||||
oldMarkedInfo = popMarkedInfo()
|
||||
if let row = self.markedInfo?.position.row, region.top <= row, row <= region.bottom {
|
||||
oldMarkedInfo = self.popMarkedInfo()
|
||||
}
|
||||
defer {
|
||||
// keep markedInfo position not changed. markedInfo only following cursor position change
|
||||
@ -196,7 +196,7 @@ final class UGrid: CustomStringConvertible, Codable {
|
||||
repeating: UCell(string: clearString, attrId: CellAttributesCollection.defaultAttributesId),
|
||||
count: self.size.width
|
||||
)
|
||||
updateMarkedInfo(newValue: nil) // everything need to be reset
|
||||
self.updateMarkedInfo(newValue: nil) // everything need to be reset
|
||||
self.cells = Array(repeating: emptyRow, count: self.size.height)
|
||||
}
|
||||
|
||||
@ -236,7 +236,7 @@ final class UGrid: CustomStringConvertible, Codable {
|
||||
// remove marked patch and recover after modified from vim
|
||||
var oldMarkedInfo: MarkedInfo?
|
||||
if row == self.markedInfo?.position.row {
|
||||
oldMarkedInfo = popMarkedInfo()
|
||||
oldMarkedInfo = self.popMarkedInfo()
|
||||
}
|
||||
defer {
|
||||
if let oldMarkedInfo = oldMarkedInfo {
|
||||
@ -258,73 +258,82 @@ final class UGrid: CustomStringConvertible, Codable {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct MarkedInfo {
|
||||
var position: Position
|
||||
var markedCell: [UCell]
|
||||
var selectedRange: NSRange // begin from markedCell and calculate by ucell count
|
||||
var position: Position
|
||||
var markedCell: [UCell]
|
||||
var selectedRange: NSRange // begin from markedCell and calculate by ucell count
|
||||
}
|
||||
|
||||
var _markedInfo: MarkedInfo?
|
||||
func popMarkedInfo() -> MarkedInfo? {
|
||||
if let markedInfo = _markedInfo {
|
||||
// true clear or just popup
|
||||
updateMarkedInfo(newValue: nil)
|
||||
return markedInfo
|
||||
}
|
||||
return nil
|
||||
if let markedInfo = _markedInfo {
|
||||
// true clear or just popup
|
||||
self.updateMarkedInfo(newValue: nil)
|
||||
return markedInfo
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// return changedRowStart. Int.max if no change
|
||||
@discardableResult
|
||||
func updateMarkedInfo(newValue: MarkedInfo?) -> Int {
|
||||
assert(Thread.isMainThread, "should occur on main thread!")
|
||||
var changedRowStart = Int.max
|
||||
if let old = _markedInfo {
|
||||
self.cells[old.position.row].removeSubrange(old.position.column..<(old.position.column+old.markedCell.count))
|
||||
self.cells[old.position.row]
|
||||
.removeSubrange(old.position.column..<(old.position.column + old.markedCell.count))
|
||||
changedRowStart = old.position.row
|
||||
}
|
||||
_markedInfo = newValue
|
||||
self._markedInfo = newValue
|
||||
if let new = newValue {
|
||||
self.cells[new.position.row].insert(contentsOf: new.markedCell, at: new.position.column)
|
||||
changedRowStart = min(changedRowStart, new.position.row)
|
||||
}
|
||||
return changedRowStart
|
||||
}
|
||||
|
||||
var markedInfo: MarkedInfo? {
|
||||
get { _markedInfo }
|
||||
set {
|
||||
let changedRowStart = updateMarkedInfo(newValue: newValue)
|
||||
if changedRowStart < self.size.height {
|
||||
recomputeFlatIndices(rowStart: changedRowStart)
|
||||
}
|
||||
get { self._markedInfo }
|
||||
set {
|
||||
let changedRowStart = self.updateMarkedInfo(newValue: newValue)
|
||||
if changedRowStart < self.size.height {
|
||||
self.recomputeFlatIndices(rowStart: changedRowStart)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cursorPositionWithMarkedInfo(allowOverflow: Bool = false) -> Position {
|
||||
var position: Position = cursorPosition
|
||||
var position: Position = self.cursorPosition
|
||||
if let markedInfo = markedInfo { position.column += markedInfo.selectedRange.location }
|
||||
if !allowOverflow, position.column >= size.width { position.column = size.width - 1 }
|
||||
if !allowOverflow, position.column >= self.size.width { position.column = self.size.width - 1 }
|
||||
return position
|
||||
}
|
||||
|
||||
// marked text insert into cell directly
|
||||
// marked text always following cursor position
|
||||
func updateMark(
|
||||
markedText: String,
|
||||
selectedRange: NSRange
|
||||
markedText: String,
|
||||
selectedRange: NSRange
|
||||
) {
|
||||
assert(Thread.isMainThread, "should occur on main thread!")
|
||||
var selectedRangeByCell = selectedRange
|
||||
let markedTextArray: [String] = markedText.enumerated().reduce(into: []) { (array, pair) in
|
||||
array.append(String(pair.element))
|
||||
if !KeyUtils.isHalfWidth(char: pair.element) {
|
||||
array.append("")
|
||||
if pair.offset < selectedRange.location { selectedRangeByCell.location += 1 }
|
||||
else { selectedRangeByCell.length += 1 }
|
||||
}
|
||||
assert(Thread.isMainThread, "should occur on main thread!")
|
||||
var selectedRangeByCell = selectedRange
|
||||
let markedTextArray: [String] = markedText.enumerated().reduce(into: []) { array, pair in
|
||||
array.append(String(pair.element))
|
||||
if !KeyUtils.isHalfWidth(char: pair.element) {
|
||||
array.append("")
|
||||
if pair.offset < selectedRange.location { selectedRangeByCell.location += 1 }
|
||||
else { selectedRangeByCell.length += 1 }
|
||||
}
|
||||
let cells = markedTextArray.map {
|
||||
UCell(string: $0, attrId: CellAttributesCollection.markedAttributesId)
|
||||
}
|
||||
self.markedInfo = MarkedInfo(position: cursorPosition, markedCell: cells, selectedRange: selectedRangeByCell)
|
||||
|
||||
}
|
||||
let cells = markedTextArray.map {
|
||||
UCell(string: $0, attrId: CellAttributesCollection.markedAttributesId)
|
||||
}
|
||||
self.markedInfo = MarkedInfo(
|
||||
position: self.cursorPosition,
|
||||
markedCell: cells,
|
||||
selectedRange: selectedRangeByCell
|
||||
)
|
||||
}
|
||||
|
||||
func recomputeFlatIndices(rowStart: Int) {
|
||||
@ -336,7 +345,7 @@ final class UGrid: CustomStringConvertible, Codable {
|
||||
}
|
||||
|
||||
// should update following char too since previous line is change
|
||||
for row in rowStart...(size.height - 1) {
|
||||
for row in rowStart...(self.size.height - 1) {
|
||||
// marked text may overflow size, counter it too
|
||||
for column in self.cells[row].indices {
|
||||
if self.cells[row][column].string.isEmpty { counter -= 1 }
|
||||
|
@ -279,7 +279,7 @@ final class UiBridge {
|
||||
process.launchPath = Bundle.module.url(forResource: "NvimServer", withExtension: nil)!.path
|
||||
process
|
||||
.arguments = [self.localServerName, self.remoteServerName, usesCustomTabBarArg] +
|
||||
["--headless"] + self.nvimArgs
|
||||
["--headless"] + self.nvimArgs
|
||||
|
||||
self.log.debug(
|
||||
"Launching NvimServer with args: \(String(describing: process.arguments))"
|
||||
|
@ -432,40 +432,41 @@ class TypesetterWithLigaturesTest: XCTestCase {
|
||||
)
|
||||
expect(runs).to(haveCount(4))
|
||||
|
||||
// newest xcode(13.1) will crash at the follwing code, by use var run, and call expect(run.positions[0]). avoid crash
|
||||
// newest xcode(13.1) will crash at the follwing code, by use var run, and call
|
||||
// expect(run.positions[0]). avoid crash
|
||||
do {
|
||||
// The positions of the combining characters are copied from print outputs
|
||||
// and they are visually checked by drawing them and inspecting them...
|
||||
let run = runs[0]
|
||||
expect(run.font).to(equalFont(courierNew))
|
||||
expect(run.glyphs).to(haveCount(2))
|
||||
expect(run.positions[0])
|
||||
.to(equal(CGPoint(x: offset.x + 1 * defaultWidth, y: offset.y)))
|
||||
expect(run.positions[1].x)
|
||||
.to(beCloseTo(offset.x + 1 * defaultWidth + 0.003, within: 0.001))
|
||||
expect(run.positions[1].y).to(beCloseTo(offset.y + 0.305, within: 0.001))
|
||||
// The positions of the combining characters are copied from print outputs
|
||||
// and they are visually checked by drawing them and inspecting them...
|
||||
let run = runs[0]
|
||||
expect(run.font).to(equalFont(courierNew))
|
||||
expect(run.glyphs).to(haveCount(2))
|
||||
expect(run.positions[0])
|
||||
.to(equal(CGPoint(x: offset.x + 1 * defaultWidth, y: offset.y)))
|
||||
expect(run.positions[1].x)
|
||||
.to(beCloseTo(offset.x + 1 * defaultWidth + 0.003, within: 0.001))
|
||||
expect(run.positions[1].y).to(beCloseTo(offset.y + 0.305, within: 0.001))
|
||||
}
|
||||
|
||||
do {
|
||||
let run = runs[1]
|
||||
expect(run.font).to(equalFont(defaultFont))
|
||||
expect(run.glyphs).to(haveCount(2))
|
||||
expect(run.positions[0])
|
||||
.to(equal(CGPoint(x: offset.x + 2 * defaultWidth, y: offset.y)))
|
||||
expect(run.positions[1].x)
|
||||
.to(beCloseTo(offset.x + 2 * defaultWidth, within: 0.001))
|
||||
expect(run.positions[1].y).to(beCloseTo(offset.y - 0.279, within: 0.001))
|
||||
let run = runs[1]
|
||||
expect(run.font).to(equalFont(defaultFont))
|
||||
expect(run.glyphs).to(haveCount(2))
|
||||
expect(run.positions[0])
|
||||
.to(equal(CGPoint(x: offset.x + 2 * defaultWidth, y: offset.y)))
|
||||
expect(run.positions[1].x)
|
||||
.to(beCloseTo(offset.x + 2 * defaultWidth, within: 0.001))
|
||||
expect(run.positions[1].y).to(beCloseTo(offset.y - 0.279, within: 0.001))
|
||||
}
|
||||
|
||||
do {
|
||||
let run = runs[2]
|
||||
expect(run.font).to(equalFont(monaco))
|
||||
expect(run.glyphs).to(haveCount(2))
|
||||
expect(run.positions[0])
|
||||
.to(equal(CGPoint(x: offset.x + 3 * defaultWidth, y: offset.y)))
|
||||
expect(run.positions[1].x)
|
||||
.to(beCloseTo(offset.x + 3 * defaultWidth + 7.804, within: 0.001))
|
||||
expect(run.positions[1].y).to(beCloseTo(offset.y + 2.446, within: 0.001))
|
||||
let run = runs[2]
|
||||
expect(run.font).to(equalFont(monaco))
|
||||
expect(run.glyphs).to(haveCount(2))
|
||||
expect(run.positions[0])
|
||||
.to(equal(CGPoint(x: offset.x + 3 * defaultWidth, y: offset.y)))
|
||||
expect(run.positions[1].x)
|
||||
.to(beCloseTo(offset.x + 3 * defaultWidth + 7.804, within: 0.001))
|
||||
expect(run.positions[1].y).to(beCloseTo(offset.y + 2.446, within: 0.001))
|
||||
}
|
||||
|
||||
self.assertEmojiMarker(run: runs[3], xPosition: offset.x + 4 * defaultWidth)
|
||||
|
@ -2,8 +2,8 @@
|
||||
/// See LICENSE
|
||||
|
||||
import Foundation
|
||||
import RxSwift
|
||||
import RxPack
|
||||
import RxSwift
|
||||
|
||||
public final class RxNeovimApi {
|
||||
public enum Event {
|
||||
|
@ -84,7 +84,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
})
|
||||
.disposed(by: self.disposeBag)
|
||||
|
||||
self.server.syncReplyBody = { (msgid, data) -> Data? in
|
||||
self.server.syncReplyBody = { msgid, data -> Data? in
|
||||
DispatchQueue.main.async {
|
||||
self.logServer("Preparing synchronous reply to (\(msgid), \(String(describing: data)))")
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ final class Context: ReduxContext {
|
||||
rpcEpic.apply,
|
||||
]
|
||||
)
|
||||
.filter { $0.modified }
|
||||
.filter(\.modified)
|
||||
.subscribe(onNext: self.emitAppState)
|
||||
.disposed(by: self.disposeBag)
|
||||
|
||||
@ -86,7 +86,7 @@ final class Context: ReduxContext {
|
||||
httpMiddleware.htmlPreviewTool.apply,
|
||||
]
|
||||
)
|
||||
.filter { $0.modified }
|
||||
.filter(\.modified)
|
||||
.subscribe(onNext: self.emitAppState)
|
||||
.disposed(by: self.disposeBag)
|
||||
}
|
||||
|
@ -461,7 +461,9 @@ extension FileOutlineView {
|
||||
override func validateUserInterfaceItem(_ item: NSValidatedUserInterfaceItem) -> Bool {
|
||||
guard let clickedNode = self.node(from: self.clickedItem) else { return true }
|
||||
|
||||
if item.action == #selector(self.setAsWorkingDirectory(_:)) { return clickedNode.url.hasDirectoryPath }
|
||||
if item
|
||||
.action ==
|
||||
#selector(self.setAsWorkingDirectory(_:)) { return clickedNode.url.hasDirectoryPath }
|
||||
|
||||
return true
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import os
|
||||
|
||||
extension URL {
|
||||
var direntType: Int16 {
|
||||
if self.isRegularFile { return Int16(DT_REG)}
|
||||
if self.isRegularFile { return Int16(DT_REG) }
|
||||
if self.hasDirectoryPath { return Int16(DT_DIR) }
|
||||
|
||||
return Int16(DT_UNKNOWN)
|
||||
|
@ -7,8 +7,8 @@ import Commons
|
||||
import CoreData
|
||||
import Foundation
|
||||
import Ignore
|
||||
import os
|
||||
import Misc
|
||||
import os
|
||||
|
||||
final class FuzzySearchService {
|
||||
typealias ScoredUrlsCallback = ([ScoredUrl]) -> Void
|
||||
|
@ -71,9 +71,12 @@ final class HttpServerMiddleware {
|
||||
typealias StateType = MainWindow.State
|
||||
typealias ActionType = UuidAction<MainWindow.Action>
|
||||
|
||||
fileprivate init(server: HttpServer, baseUrl: URL, cssUrl: URL,
|
||||
htmlTemplates _: HtmlTemplates)
|
||||
{
|
||||
fileprivate init(
|
||||
server: HttpServer,
|
||||
baseUrl: URL,
|
||||
cssUrl: URL,
|
||||
htmlTemplates _: HtmlTemplates
|
||||
) {
|
||||
self.server = server
|
||||
self.baseUrl = baseUrl
|
||||
self.cssUrl = cssUrl
|
||||
@ -122,9 +125,12 @@ final class HttpServerMiddleware {
|
||||
typealias StateType = MainWindow.State
|
||||
typealias ActionType = UuidAction<HtmlPreviewTool.Action>
|
||||
|
||||
fileprivate init(server: HttpServer, baseUrl: URL, cssUrl: URL,
|
||||
htmlTemplates _: HtmlTemplates)
|
||||
{
|
||||
fileprivate init(
|
||||
server: HttpServer,
|
||||
baseUrl: URL,
|
||||
cssUrl: URL,
|
||||
htmlTemplates _: HtmlTemplates
|
||||
) {
|
||||
self.server = server
|
||||
self.baseUrl = baseUrl
|
||||
self.cssUrl = cssUrl
|
||||
|
@ -23,12 +23,11 @@ extension MainWindow {
|
||||
let params = Array(rawParams.suffix(from: 1))
|
||||
|
||||
switch event {
|
||||
|
||||
case .refreshFileBrowser:
|
||||
self.refreshFileBrowser()
|
||||
self.refreshFileBrowser()
|
||||
|
||||
case .revealCurrentBufferInFileBrowser:
|
||||
self.revealCurrentBufferInFileBrowser()
|
||||
self.revealCurrentBufferInFileBrowser()
|
||||
|
||||
case .makeSessionTemporary:
|
||||
self.emit(self.uuidAction(for: .makeSessionTemporary))
|
||||
|
@ -93,7 +93,8 @@ extension MainWindow {
|
||||
|
||||
if let button = self.window.standardWindowButton(.documentIconButton) {
|
||||
button
|
||||
.removeFromSuperview() // remove the rep icon from the original superview and add it to content view
|
||||
.removeFromSuperview() // remove the rep icon from the original superview and add it to
|
||||
// content view
|
||||
contentView.addSubview(button)
|
||||
button.autoSetDimension(.width, toSize: 16)
|
||||
button.autoSetDimension(.height, toSize: 16)
|
||||
@ -113,7 +114,8 @@ extension MainWindow {
|
||||
constant: repIconToTitleGap
|
||||
))
|
||||
contentView.addConstraint(
|
||||
// Here we use title.intrinsicContentSize instead of title.frame because title.frame is still zero.
|
||||
// Here we use title.intrinsicContentSize instead of title.frame because title.frame is
|
||||
// still zero.
|
||||
NSLayoutConstraint(
|
||||
item: title, attribute: .right,
|
||||
relatedBy: .equal,
|
||||
|
@ -5,9 +5,9 @@
|
||||
|
||||
import Cocoa
|
||||
import NvimView
|
||||
import RxNeovim
|
||||
import RxPack
|
||||
import RxSwift
|
||||
import RxNeovim
|
||||
import Workspace
|
||||
|
||||
// MARK: - NvimViewDelegate
|
||||
@ -30,7 +30,8 @@ extension MainWindow {
|
||||
func prepareClosing() {
|
||||
self.isClosing = true
|
||||
|
||||
// If we close the window in the full screen mode, either by clicking the close button or by invoking :q
|
||||
// If we close the window in the full screen mode, either by clicking the close button or by
|
||||
// invoking :q
|
||||
// the main thread crashes. We exit the full screen mode here as a quick and dirty hack.
|
||||
if self.window.styleMask.contains(.fullScreen) {
|
||||
self.window.toggleFullScreen(nil)
|
||||
@ -69,7 +70,7 @@ extension MainWindow {
|
||||
self.neoVimView
|
||||
.allBuffers()
|
||||
.subscribe(onSuccess: { buffers in
|
||||
self.emit(self.uuidAction(for: .setBufferList(buffers.filter { $0.isListed })))
|
||||
self.emit(self.uuidAction(for: .setBufferList(buffers.filter(\.isListed))))
|
||||
})
|
||||
.disposed(by: self.disposeBag)
|
||||
}
|
||||
|
@ -595,7 +595,7 @@ final class MainWindow: NSObject,
|
||||
Swift.print("fdsfd")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func revealCurrentBufferInFileBrowser() {
|
||||
self.fileBrowser?.scrollToSourceAction(nil)
|
||||
}
|
||||
|
@ -143,9 +143,11 @@ final class MarkdownTool: NSView, UiComponent, WKNavigationDelegate {
|
||||
self.webview.autoPinEdgesToSuperviewEdges()
|
||||
}
|
||||
|
||||
func webView(_: WKWebView, didFailProvisionalNavigation _: WKNavigation!,
|
||||
withError error: Error)
|
||||
{
|
||||
func webView(
|
||||
_: WKWebView,
|
||||
didFailProvisionalNavigation _: WKNavigation!,
|
||||
withError error: Error
|
||||
) {
|
||||
self.log.error("ERROR preview component's webview: \(error)")
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,8 @@
|
||||
import Cocoa
|
||||
|
||||
class PrefPane: NSView {
|
||||
// Return true to place this to the upper left corner when the scroll view is bigger than this view.
|
||||
// Return true to place this to the upper left corner when the scroll view is bigger than this
|
||||
// view.
|
||||
override var isFlipped: Bool {
|
||||
true
|
||||
}
|
||||
|
@ -19,9 +19,11 @@ final class PrefUtils {
|
||||
dict[key] as? [String: Any]
|
||||
}
|
||||
|
||||
static func float(from dict: [String: Any], for key: String,
|
||||
default defaultValue: Float) -> Float
|
||||
{
|
||||
static func float(
|
||||
from dict: [String: Any],
|
||||
for key: String,
|
||||
default defaultValue: Float
|
||||
) -> Float {
|
||||
(dict[key] as? NSNumber)?.floatValue ?? defaultValue
|
||||
}
|
||||
|
||||
@ -49,9 +51,11 @@ final class PrefUtils {
|
||||
dict[key] as? String
|
||||
}
|
||||
|
||||
static func string(from dict: [String: Any], for key: String,
|
||||
default defaultValue: String) -> String
|
||||
{
|
||||
static func string(
|
||||
from dict: [String: Any],
|
||||
for key: String,
|
||||
default defaultValue: String
|
||||
) -> String {
|
||||
dict[key] as? String ?? defaultValue
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,8 @@ enum RpcEvent: String, CaseIterable {
|
||||
case setFont = "com.qvacua.vimr.rpc-events.set-font"
|
||||
case setLinespacing = "com.qvacua.vimr.rpc-events.set-linespacing"
|
||||
case setCharacterspacing = "com.qvacua.vimr.rpc-events.set-characterspacing"
|
||||
|
||||
case revealCurrentBufferInFileBrowser = "com.qvacua.vimr.rpc-events.reveal-current-buffer-in-file-browser"
|
||||
|
||||
case revealCurrentBufferInFileBrowser =
|
||||
"com.qvacua.vimr.rpc-events.reveal-current-buffer-in-file-browser"
|
||||
case refreshFileBrowser = "com.qvacua.vimr.rpc-events.refresh-file-browser"
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ class ReduxContext {
|
||||
self.actionEmitter.observable
|
||||
.map { (state: self.state, action: $0, modified: false) }
|
||||
.reduce(by: reducers, middlewares: middlewares)
|
||||
.filter { $0.modified }
|
||||
.filter(\.modified)
|
||||
.subscribe(onNext: { tuple in
|
||||
self.state = tuple.state
|
||||
self.stateSubject.onNext(tuple.state)
|
||||
|
@ -7,9 +7,13 @@ import Cocoa
|
||||
import Commons
|
||||
import NvimView
|
||||
|
||||
func changeTheme(themePrefChanged: Bool, themeChanged: Bool, usesTheme: Bool,
|
||||
forTheme: () -> Void, forDefaultTheme: () -> Void) -> Bool
|
||||
{
|
||||
func changeTheme(
|
||||
themePrefChanged: Bool,
|
||||
themeChanged: Bool,
|
||||
usesTheme: Bool,
|
||||
forTheme: () -> Void,
|
||||
forDefaultTheme: () -> Void
|
||||
) -> Bool {
|
||||
if themePrefChanged, usesTheme {
|
||||
forTheme()
|
||||
return true
|
||||
|
@ -69,13 +69,15 @@ final class ThemedTableCell: NSTableCellView {
|
||||
static let widthWithoutText = (2 + 16 + 4 + 2).cgf
|
||||
|
||||
// static func width(with text: String) -> CGFloat {
|
||||
// let attrStr = NSAttributedString(string: text, attributes: [NSAttributedString.Key.font: ThemedTableCell.font])
|
||||
// let attrStr = NSAttributedString(string: text, attributes: [NSAttributedString.Key.font:
|
||||
// ThemedTableCell.font])
|
||||
//
|
||||
// return self.widthWithoutText + attrStr.size().width
|
||||
// }
|
||||
//
|
||||
// override var intrinsicContentSize: CGSize {
|
||||
// return CGSize(width: ThemedTableCell.widthWithoutText + self._textField.intrinsicContentSize.width,
|
||||
// return CGSize(width: ThemedTableCell.widthWithoutText +
|
||||
// self._textField.intrinsicContentSize.width,
|
||||
// height: max(self._textField.intrinsicContentSize.height, 16))
|
||||
// }
|
||||
|
||||
|
@ -63,7 +63,7 @@ final class Marked<T>: CustomStringConvertible {
|
||||
let payload: T
|
||||
|
||||
var description: String {
|
||||
"Marked<\(mark) -> \(self.payload)>"
|
||||
"Marked<\(self.mark) -> \(self.payload)>"
|
||||
}
|
||||
|
||||
init(_ payload: T) {
|
||||
|
@ -107,10 +107,11 @@ final class UiRootReducer: ReducerType {
|
||||
return (appState, tuple.action, true)
|
||||
}
|
||||
|
||||
private func mainWindowTemplate(from old: MainWindow.State,
|
||||
new: MainWindow.State,
|
||||
isFullScreen: Bool) -> MainWindow.State
|
||||
{
|
||||
private func mainWindowTemplate(
|
||||
from old: MainWindow.State,
|
||||
new: MainWindow.State,
|
||||
isFullScreen: Bool
|
||||
) -> MainWindow.State {
|
||||
var result = old
|
||||
|
||||
if !isFullScreen {
|
||||
|
@ -14,13 +14,13 @@ class IgnoreServiceTest: XCTestCase {
|
||||
withExtension: nil,
|
||||
subdirectory: "Resources"
|
||||
)!
|
||||
self.service = IgnoreService(count: 100, root: base)
|
||||
self.service = IgnoreService(count: 100, root: self.base)
|
||||
|
||||
super.setUp()
|
||||
}
|
||||
|
||||
func testDeepest() {
|
||||
let ignoreAaa = service.ignore(for: base.appendingPathComponent("a/aa/aaa"))!
|
||||
let ignoreAaa = self.service.ignore(for: self.base.appendingPathComponent("a/aa/aaa"))!
|
||||
|
||||
expect(ignoreAaa.filters.count).to(beGreaterThanOrEqualTo(4))
|
||||
expect(ignoreAaa.filters[back: 0].pattern).to(equal("last-level"))
|
||||
@ -30,10 +30,10 @@ class IgnoreServiceTest: XCTestCase {
|
||||
}
|
||||
|
||||
func testWholeTree() {
|
||||
let ignoreBase = service.ignore(for: base)!
|
||||
let ignoreA = service.ignore(for: base.appendingPathComponent("a/"))!
|
||||
let ignoreAa = service.ignore(for: base.appendingPathComponent("a/aa/"))!
|
||||
let ignoreAaa = service.ignore(for: base.appendingPathComponent("a/aa/aaa"))!
|
||||
let ignoreBase = self.service.ignore(for: self.base)!
|
||||
let ignoreA = self.service.ignore(for: self.base.appendingPathComponent("a/"))!
|
||||
let ignoreAa = self.service.ignore(for: self.base.appendingPathComponent("a/aa/"))!
|
||||
let ignoreAaa = self.service.ignore(for: self.base.appendingPathComponent("a/aa/aaa"))!
|
||||
|
||||
expect(ignoreBase.filters.count).to(beGreaterThanOrEqualTo(1))
|
||||
expect(ignoreBase.filters[back: 0].pattern).to(equal("root-level"))
|
||||
|
@ -52,7 +52,8 @@ public final class InnerToolBar: NSView, NSUserInterfaceValidations {
|
||||
super.init(frame: .zero)
|
||||
self.configureForAutoLayout()
|
||||
|
||||
// Because other views also want layer, this view also must want layer. Otherwise the z-index ordering is not set
|
||||
// Because other views also want layer, this view also must want layer. Otherwise the z-index
|
||||
// ordering is not set
|
||||
// correctly: views w/ wantsLayer = false are behind views w/ wantsLayer = true even when added later.
|
||||
self.wantsLayer = true
|
||||
self.layer?.backgroundColor = self.theme.toolbarBackground.cgColor
|
||||
|
@ -20,7 +20,8 @@ final class ProxyWorkspaceBar: NSView {
|
||||
override init(frame: NSRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
// Because other views also want layer, this view also must want layer. Otherwise the z-index ordering is not set
|
||||
// Because other views also want layer, this view also must want layer. Otherwise the z-index
|
||||
// ordering is not set
|
||||
// correctly: views w/ wantsLayer = false are behind views w/ wantsLayer = true even when added later.
|
||||
self.wantsLayer = true
|
||||
self.layer?.backgroundColor = self.theme.background.cgColor
|
||||
|
@ -271,7 +271,8 @@ private extension Workspace {
|
||||
|
||||
private 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...
|
||||
// and remove them here by self.removeConstraints(${all constraints). The following seems to
|
||||
// work...
|
||||
self.subviews.forEach { $0.removeAllConstraints() }
|
||||
self.removeAllSubviews()
|
||||
|
||||
|
@ -274,7 +274,7 @@ extension ProxyBar {
|
||||
let locInBar = self.convert(locInProxy, to: self.container)
|
||||
|
||||
let currentDraggedOnToolIdx = self.buttonFrames.enumerated()
|
||||
.reduce(nil) { (result, entry) -> Int? in
|
||||
.reduce(nil) { result, entry -> Int? in
|
||||
if result != nil {
|
||||
return result
|
||||
}
|
||||
|
@ -50,13 +50,14 @@ public final class WorkspaceTool: NSView {
|
||||
let customToolbar: CustomToolBar?
|
||||
let customMenuItems: [NSMenuItem]
|
||||
|
||||
public init(title: String,
|
||||
view: NSView,
|
||||
minimumDimension: CGFloat = 50,
|
||||
withInnerToolbar: Bool = true,
|
||||
customToolbar: CustomToolBar? = nil,
|
||||
customMenuItems: [NSMenuItem] = [])
|
||||
{
|
||||
public init(
|
||||
title: String,
|
||||
view: NSView,
|
||||
minimumDimension: CGFloat = 50,
|
||||
withInnerToolbar: Bool = true,
|
||||
customToolbar: CustomToolBar? = nil,
|
||||
customMenuItems: [NSMenuItem] = []
|
||||
) {
|
||||
self.title = title
|
||||
self.view = view
|
||||
self.minimumDimension = minimumDimension
|
||||
|
@ -198,7 +198,8 @@ public extension WorkspaceToolButton {
|
||||
self.dehighlight()
|
||||
}
|
||||
|
||||
// Modified version of snapshot() from https://www.raywenderlich.com/136272/drag-and-drop-tutorial-for-macos
|
||||
// Modified version of snapshot() from
|
||||
// https://www.raywenderlich.com/136272/drag-and-drop-tutorial-for-macos
|
||||
private func snapshot() -> NSImage {
|
||||
let pdfData = self.dataWithPDF(inside: self.bounds)
|
||||
guard let image = NSImage(data: pdfData) else {
|
||||
@ -223,9 +224,10 @@ public extension WorkspaceToolButton {
|
||||
|
||||
public extension WorkspaceToolButton {
|
||||
@objc(draggingSession: sourceOperationMaskForDraggingContext:)
|
||||
func draggingSession(_: NSDraggingSession,
|
||||
sourceOperationMaskFor _: NSDraggingContext) -> NSDragOperation
|
||||
{
|
||||
func draggingSession(
|
||||
_: NSDraggingSession,
|
||||
sourceOperationMaskFor _: NSDraggingContext
|
||||
) -> NSDragOperation {
|
||||
.move
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user