1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-12-25 14:52:19 +03:00

Merge remote-tracking branch 'origin/develop' into update-neovim

This commit is contained in:
Tae Won Ha 2022-06-16 15:55:57 +02:00
commit 076768bdfb
No known key found for this signature in database
GPG Key ID: E40743465B5B8B44
92 changed files with 1209 additions and 1827 deletions

View File

@ -1,58 +0,0 @@
name: "VimR deps release on tag"
on:
push:
tags:
- 'vimr-deps-*'
jobs:
Build-universal:
runs-on: macos-11
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Install brew packages
run: |
brew update >/dev/null
brew upgrade
brew install automake coreutils pyenv pyenv-virtualenv
- name: Set up Python env
run: |
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
pyenv install 3.9.7
pyenv virtualenv 3.9.7 com.qvacua.VimR.bin
pushd bin >/dev/null
pip install -r requirements.txt
python setup.py develop
popd >/dev/null
- name: Build deps
run: |
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
./bin/build_deps.sh
- name: Create release and upload artifact
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
pushd bin/third_party >/dev/null
tar cjf vimr-deps.tar.bz2 vimr-deps
gh release create -p ${{ github.ref_name }}
gh release upload ${{ github.ref_name }} vimr-deps.tar.bz2
popd >/dev/null
- uses: actions/upload-artifact@v2
with:
name: vimr-deps
path: bin/third_party/vimr-deps
if-no-files-found: error
retention-days: 7

View File

@ -1,4 +1,4 @@
// swift-tools-version:5.3
// swift-tools-version:5.6
import PackageDescription
@ -9,7 +9,7 @@ let package = Package(
.library(name: "Commons", targets: ["Commons", "CommonsObjC"]),
],
dependencies: [
.package(url: "https://github.com/Quick/Nimble", .upToNextMinor(from: "9.2.1")),
.package(url: "https://github.com/Quick/Nimble", from: "10.0.0"),
],
targets: [
.target(name: "Commons", dependencies: []),

View File

@ -10,10 +10,10 @@ private let iconsCache = NSCache<NSURL, NSImage>()
public final class FileUtils {
private static let keysToGet: [URLResourceKey] = [
.isRegularFileKey,
.isDirectoryKey,
.isPackageKey,
.isHiddenKey,
.isAliasFileKey,
.isSymbolicLinkKey,
]
private static let scanOptions: FileManager.DirectoryEnumerationOptions = [
@ -56,7 +56,7 @@ public final class FileUtils {
let result = pathCompsOnlyMin[0]
let possibleParent = NSURL.fileURL(withPathComponents: Array(result[0...commonIdx]))!
return possibleParent.isDir ? possibleParent : possibleParent.parent
return possibleParent.hasDirectoryPath ? possibleParent : possibleParent.parent
}
public static func icon(forType type: String) -> NSImage { workspace.icon(forFileType: type) }

View File

@ -125,34 +125,13 @@ public extension URL {
var shellEscapedPath: String { self.path.shellEscapedPath }
var isDir: Bool { self.resourceValue(URLResourceKey.isDirectoryKey.rawValue) }
var isHidden: Bool { self.resourceValue(URLResourceKey.isHiddenKey.rawValue) }
var isPackage: Bool { self.resourceValue(URLResourceKey.isPackageKey.rawValue) }
/// Wrapper function for NSURL.getResourceValue for Bool values.
/// Returns also `false` when
/// - there is no value for the given `key` or
/// - the value cannot be converted to `NSNumber`.
///
/// - parameters:
/// - key: The `key`-parameter of `NSURL.getResourceValue`.
private func resourceValue(_ key: String) -> Bool {
var rsrc: AnyObject?
do {
try (self as NSURL).getResourceValue(&rsrc, forKey: URLResourceKey(rawValue: key))
} catch let error as NSError {
// FIXME: How to error handle?
log.error("ERROR while getting \(key): \(error)")
return false
}
if let result = rsrc as? NSNumber { return result.boolValue }
return false
var isRegularFile: Bool {
(try? self.resourceValues(forKeys: [.isRegularFileKey]))?.isRegularFile ?? false
}
var isHidden: Bool { (try? self.resourceValues(forKeys: [.isHiddenKey]))?.isHidden ?? false }
var isPackage: Bool { (try? self.resourceValues(forKeys: [.isPackageKey]))?.isPackage ?? false }
}
public extension ValueTransformer {

View File

@ -90,7 +90,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1200;
LastUpgradeCheck = 1330;
LastUpgradeCheck = 1340;
TargetAttributes = {
4B7FBFF724EC936C002D12A1 = {
CreatedOnToolsVersion = 12.0;

View File

@ -53,25 +53,18 @@ then continuously invoke the `build_nvimserver_for_local_dev` script.
### VimR
#### Dependencies
* Tag with the name `vimr-deps-yyyy-mm-dd`. GitHub actions will build the universal version,
create a release and upload it.
* Update `resources/vimr-deps_version.txt` and push.
#### Executable
* Set a new version of VimR via
```bash
is_snapshot=true ./bin/set_new_versions.sh # for snapshot or
is_snapshot=false marketing_version=0.38.3 ./bin/set_new_versions.sh # for release
```
and commit. This will create a `${bundle_version}-snapshot/release.sh` file to be used
with `build_release.sh`.
with `build_release.sh` and `release-notes.temp.md` for release notes.
* Tag with the name
- Snapshot: `snapshot/yyyymmdd.HHMMSS`
- Release: `vX.Y.Z-yyyymmdd.HHMMSS`
* Push
* Add release notes to `release-notes.temp.md`.
* Build, package and upload via
```bash
create_gh_release=true upload=true update_appcast=true \

23
Ignore/Package.swift Normal file
View File

@ -0,0 +1,23 @@
// swift-tools-version:5.6
import PackageDescription
let package = Package(
name: "Ignore",
platforms: [.macOS(.v10_13)],
products: [
.library(name: "Ignore", targets: ["Ignore"]),
],
dependencies: [
.package(url: "https://github.com/qvacua/misc.swift", exact: "0.0.1"),
.package(url: "https://github.com/Quick/Nimble", from: "10.0.0"),
],
targets: [
.target(name: "Ignore", dependencies: [.product(name: "WildmatchC", package: "misc.swift")]),
.testTarget(
name: "IgnoreTests",
dependencies: ["Ignore", "Nimble"],
resources: [.copy("Resources")]
),
]
)

3
Ignore/README.md Normal file
View File

@ -0,0 +1,3 @@
# Ignore
A description of this package.

View File

@ -0,0 +1,105 @@
/// Tae Won Ha - http://taewon.de - @hataewon
/// See LICENSE
import Foundation
/// Reads the file at the given ``URL`` line by line.
/// The Unix line ending `LF` is used to determine lines.
/// Thus, it supports `LF` and `CRLF` files. It does not support the legacy Mac line ending `CR`.
public final class FileLineReader: Sequence {
public static let defaultLineBufferCount = 1024
public let url: URL
public var lineBufferCount: Int
public var encoding: String.Encoding
/// - Parameters:
/// - url: URL of the file.
/// - encoding: Encoding of the file. It's mutable.
/// After mutating, the next iterator will use the new value.
/// - lineBufferCount: The initial size of the buffer for reading lines. It's mutable.
/// After mutating, the next iterator will use the new value.
/// The default is ``FileLineReader/defaultLineBufferCount``.
public init(url: URL, encoding: String.Encoding, lineBufferCount: Int = defaultLineBufferCount) {
self.lineBufferCount = lineBufferCount
self.url = url
self.encoding = encoding
}
public func makeIterator() -> AnyIterator<String> {
guard let file = fopen(url.path, "r") else { return AnyIterator { nil } }
let iterator = LfLineIterator(
file: file,
encoding: self.encoding,
lineBufferCount: self.lineBufferCount
)
return AnyIterator { iterator.next() }
}
}
private class LfLineIterator: IteratorProtocol {
init(
file: UnsafeMutablePointer<FILE>,
encoding: String.Encoding,
lineBufferCount: Int
) {
self.file = file
self.encoding = encoding
self.buffer = Array(repeating: 0, count: lineBufferCount)
}
deinit { fclose(self.file) }
func next() -> String? {
var readCharCount = 0
while true {
let nextChar = getc(self.file)
if nextChar == EOF {
if readCharCount == 0 { return nil }
return String(
data: Data(
bytesNoCopy: self.buffer[0..<readCharCount].unsafeMutableRawPointer,
count: readCharCount,
deallocator: .none
), encoding: self.encoding
)
}
if readCharCount >= self.buffer.count {
// Array.append()
// https://developer.apple.com/documentation/swift/array/3126937-append
// "Complexity: O(1) on average, over many calls to append(_:) on the same array."
self.buffer.append(UInt8(nextChar))
} else {
self.buffer[readCharCount] = UInt8(nextChar)
}
readCharCount += 1
if nextChar == Self.unixLineEnding {
return String(
data: Data(
bytesNoCopy: self.buffer[0..<readCharCount].unsafeMutableRawPointer,
count: readCharCount,
deallocator: .none
), encoding: self.encoding
)
}
}
}
private let encoding: String.Encoding
private var buffer: [UInt8]
private let file: UnsafeMutablePointer<FILE>
private static let unixLineEnding = "\n".utf8.first!
}
private extension ArraySlice {
@inline(__always)
var unsafeMutableRawPointer: UnsafeMutableRawPointer {
UnsafeMutableRawPointer(mutating: self.withUnsafeBytes { $0.baseAddress! })
}
}

View File

@ -0,0 +1,105 @@
/// Tae Won Ha - http://taewon.de - @hataewon
/// See LICENSE
import Foundation
import WildmatchC
public struct Filter: CustomStringConvertible {
public let base: URL
public let pattern: String
public let isAllow: Bool
public let isOnlyForDirectories: Bool
public let isRelativeToBase: Bool
public init(base: URL, pattern: String) {
self.base = base
var effectivePattern: String
self.isAllow = pattern.first == "!"
effectivePattern = self.isAllow ? String(pattern.dropFirst()) : pattern
self.isOnlyForDirectories = effectivePattern.last == "/"
effectivePattern =
self.isOnlyForDirectories ? String(effectivePattern.dropLast(1)) : effectivePattern
self.isRelativeToBase = effectivePattern.contains("/")
if self.isRelativeToBase {
effectivePattern = base.path
+ (effectivePattern.first == "/" ? effectivePattern : "/" + effectivePattern)
}
self.pattern = effectivePattern
self.patternCstr = Array(self.pattern.utf8CString)
}
public func disallows(_ url: URL) -> Bool {
if self.isOnlyForDirectories {
guard url.hasDirectoryPath else { return false }
}
if self.isRelativeToBase {
let matches = self.matches(url.path)
if self.isAllow { return !matches } else { return matches }
}
let matches = self.matches(url.lastPathComponent)
if self.isAllow { return false } else { return matches }
}
public func explicitlyAllows(_ url: URL) -> Bool {
if self.isOnlyForDirectories {
guard url.hasDirectoryPath else { return false }
}
if self.isRelativeToBase {
if self.isAllow { return self.matches(url.path) }
return false
}
if self.isAllow { return self.matches(url.lastPathComponent) } else { return false }
}
/// Ignores whether the pattern is only applicable for directories.
public func disallows(_ string: String) -> Bool {
if self.isAllow { return false } else { return self.matches(string) }
}
/// Ignores whether the pattern is only applicable for directories.
public func explicitlyAllows(_ string: String) -> Bool {
if self.isAllow { return self.matches(string) }
return false
}
public func matches(_ url: URL) -> Bool {
if self.isOnlyForDirectories {
guard url.hasDirectoryPath else { return false }
}
if self.isRelativeToBase {
return url.path.withCString { stringCstr in
wildmatch(patternCstr, stringCstr, WM_WILDSTAR) == WM_MATCH
}
}
return url.lastPathComponent.withCString { stringCstr in
wildmatch(patternCstr, stringCstr, WM_WILDSTAR) == WM_MATCH
}
}
/// Ignores whether the pattern is only applicable for directories.
public func matches(_ string: String) -> Bool {
string.withCString {
stringCstr in
wildmatch(patternCstr, stringCstr, WM_WILDSTAR) == WM_MATCH
}
}
public var description: String {
"Ignore(isAllow: \(self.isAllow), isOnlyDirectory: \(self.isOnlyForDirectories), "
+ "isAbsolute: \(self.isRelativeToBase), pattern: \(self.pattern), baseUrl: \(self.base))"
}
private let patternCstr: [CChar]
}

View File

@ -0,0 +1,65 @@
/// Tae Won Ha - http://taewon.de - @hataewon
/// See LICENSE
import Foundation
public class GitUtils {
static func globalGitignoreFileUrl() -> URL? {
guard let path = shellCommandOutput(
"git config --get core.excludesFile",
workingDirectory: fm.homeDirectoryForCurrentUser
),
FileManager.default.fileExists(atPath: path)
else { return nil }
return URL(fileURLWithPath: path)
}
static func gitDirInfoExcludeUrl(base: URL, gitRoot: URL? = nil) -> URL? {
guard let gitRoot = gitRoot == nil ? gitRootUrl(base: base) : gitRoot,
let gitDirName = shellCommandOutput("git rev-parse --git-dir", workingDirectory: gitRoot)
else { return nil }
let url = gitRoot.appendingPathComponent("\(gitDirName)/info/exclude")
guard fm.fileExists(atPath: url.path) else { return nil }
return url
}
static func gitRootUrl(base: URL) -> URL? {
guard let path = shellCommandOutput("git rev-parse --show-toplevel", workingDirectory: base)
else { return nil }
return URL(fileURLWithPath: path, isDirectory: true)
}
private static func shellCommandOutput(_ command: String, workingDirectory: URL) -> String? {
let task = Process()
let pipe = Pipe()
task.currentDirectoryURL = workingDirectory
task.standardInput = nil
task.standardOutput = pipe
task.standardError = nil
task.executableURL = URL(fileURLWithPath: "/bin/sh")
task.arguments = ["-c", command]
do {
try task.run()
task.waitUntilExit()
} catch {
return nil
}
guard task.terminationStatus == 0 else { return nil }
guard let output = String(
data: pipe.fileHandleForReading.readDataToEndOfFile(),
encoding: .utf8
) else { return nil }
let result = output.trimmingCharacters(in: .whitespacesAndNewlines)
if result.isEmpty { return nil } else { return result }
}
}
private let fm = FileManager.default

View File

@ -0,0 +1,106 @@
/// Tae Won Ha - http://taewon.de - @hataewon
/// See LICENSE
import Foundation
public class Ignore {
public static let defaultIgnoreFileNames = [".ignore", ".gitignore"]
public static let vcsFolderPattern = [".svn/", ".hg/", ".git/"]
public static func globalGitignoreCollection(base: URL) -> Ignore? {
let gitRoot = GitUtils.gitRootUrl(base: base)
let urls = [
GitUtils.gitDirInfoExcludeUrl(base: base, gitRoot: gitRoot),
GitUtils.globalGitignoreFileUrl(),
].compactMap { $0 }
if urls.isEmpty { return nil }
if let gitRoot = gitRoot {
let vcsFolderFilters = self.vcsFolderPattern.map { Filter(base: gitRoot, pattern: $0) }
return Ignore(base: gitRoot, parent: nil, ignoreFileUrls: urls, prepend: vcsFolderFilters)
}
let vcsFolderFilters = self.vcsFolderPattern.map { Filter(base: base, pattern: $0) }
return Ignore(base: base, parent: nil, ignoreFileUrls: urls, prepend: vcsFolderFilters)
}
public let ignores: [Filter]
/// `ignoreFileUrls[n]` overrides `ignoreFileUrls[n + 1]`.
/// `Ignore`s of `parent` are overridden, if applicable, by the `Ignore`s found in `base`.
public init?(
base: URL,
parent: Ignore?,
ignoreFileUrls: [URL],
prepend: [Filter] = [],
append: [Filter] = []
) {
if ignoreFileUrls.isEmpty { return nil }
let urls = ignoreFileUrls.filter { fm.fileExists(atPath: $0.path) }.reversed()
self.ignores = (parent?.ignores ?? [])
+ prepend.reversed()
+ urls.flatMap {
FileLineReader(url: $0, encoding: .utf8)
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
.filter { !$0.isEmpty && !$0.starts(with: "#") }
.map { Filter(base: base, pattern: $0) }
}
+ append.reversed()
if self.ignores.isEmpty { return nil }
if let lastAllowIndex = self.ignores
.enumerated()
.filter({ _, ignore in ignore.isAllow })
.map(\.offset)
.max()
{
self.mixedIgnores = self.ignores[0...lastAllowIndex]
self.remainingDisallowIgnores = self.ignores[(lastAllowIndex + 1)...]
} else {
self.mixedIgnores = ArraySlice()
self.remainingDisallowIgnores = self.ignores[0...]
}
}
/// `ignoreFileNames[n]` overrides `ignoreFileNames[n + 1]`.
/// `Ignore`s of `parent` are overridden, if applicable, by the `Ignore`s found in `base`.
public convenience init?(
base: URL,
parent: Ignore?,
ignoreFileNames: [String] = defaultIgnoreFileNames
) {
self.init(
base: base,
parent: parent,
ignoreFileUrls: ignoreFileNames.map { base.appendingPathComponent($0) }
)
}
public func excludes(_ url: URL) -> Bool {
var isExcluded = false
for ignore in self.mixedIgnores {
if ignore.isAllow {
if ignore.matches(url) { isExcluded = false }
} else {
if ignore.matches(url) { isExcluded = true }
}
}
if isExcluded { return true }
for ignore in self.remainingDisallowIgnores {
if ignore.matches(url) { return true }
}
return false
}
let mixedIgnores: ArraySlice<Filter>
let remainingDisallowIgnores: ArraySlice<Filter>
}
private let fm = FileManager.default

View File

@ -0,0 +1,68 @@
/// Tae Won Ha - http://taewon.de - @hataewon
/// See LICENSE
@testable import Ignore
import Nimble
import XCTest
private struct TestSpec {
var fileName: String
var result: [String]
}
private let specs = [
TestSpec(fileName: "empty", result: []),
TestSpec(fileName: "unix-only-new-lines", result: ["\n", "\n", "\n"]),
TestSpec(fileName: "unix-no-line-ending-at-the-end", result: ["0123\n", "하태원\n", "abcde"]),
TestSpec(fileName: "unix-with-line-ending-at-the-end", result: ["0123\n", "하태원\n", "abcde\n"]),
TestSpec(fileName: "dos-only-new-lines", result: ["\r\n", "\r\n", "\r\n"]),
TestSpec(fileName: "dos-no-line-ending-at-the-end", result: ["0123\r\n", "하태원\r\n", "abcde"]),
TestSpec(
fileName: "dos-with-line-ending-at-the-end",
result: ["0123\r\n", "하태원\r\n", "abcde\r\n"]
),
]
final class FileLineReaderTest: XCTestCase {
func testSpecsDefaultBuffer() {
specs.forEach { spec in
let url = Bundle.module.url(
forResource: spec.fileName,
withExtension: "txt",
subdirectory: "Resources/FileLineReaderTest"
)!
let lineReader = FileLineReader(url: url, encoding: .utf8)
let lines = Array(lineReader)
expect(lines).to(equal(spec.result))
}
}
func testSpecsSmallBuffer() {
specs.forEach { spec in
let url = Bundle.module.url(
forResource: spec.fileName,
withExtension: "txt",
subdirectory: "Resources/FileLineReaderTest"
)!
let lineReader = FileLineReader(url: url, encoding: .utf8, lineBufferCount: 5)
let lines = Array(lineReader)
expect(lines).to(equal(spec.result))
}
}
func testSpecsBigBuffer() {
specs.forEach { spec in
let url = Bundle.module.url(
forResource: spec.fileName,
withExtension: "txt",
subdirectory: "Resources/FileLineReaderTest"
)!
let lineReader = FileLineReader(url: url, encoding: .utf8, lineBufferCount: 2048)
let lines = Array(lineReader)
expect(lines).to(equal(spec.result))
}
}
}

View File

@ -0,0 +1,129 @@
/// Tae Won Ha - http://taewon.de - @hataewon
/// See LICENSE
@testable import Ignore
import Nimble
import XCTest
final class FilterTest: XCTestCase {
let root = Bundle.module.url(forResource: "Resources", withExtension: nil)!
func testProperties() {
var ignore = Filter(base: root, pattern: "/a")
expect(ignore.isAllow).to(beFalse())
expect(ignore.isRelativeToBase).to(beTrue())
expect(ignore.isOnlyForDirectories).to(beFalse())
ignore = Filter(base: self.root, pattern: "a/b")
expect(ignore.isAllow).to(beFalse())
expect(ignore.isRelativeToBase).to(beTrue())
expect(ignore.isOnlyForDirectories).to(beFalse())
ignore = Filter(base: self.root, pattern: "a/b/")
expect(ignore.isAllow).to(beFalse())
expect(ignore.isRelativeToBase).to(beTrue())
expect(ignore.isOnlyForDirectories).to(beTrue())
ignore = Filter(base: self.root, pattern: "a/")
expect(ignore.isAllow).to(beFalse())
expect(ignore.isRelativeToBase).to(beFalse())
expect(ignore.isOnlyForDirectories).to(beTrue())
ignore = Filter(base: self.root, pattern: "!a/")
expect(ignore.isAllow).to(beTrue())
expect(ignore.isRelativeToBase).to(beFalse())
expect(ignore.isOnlyForDirectories).to(beTrue())
}
func testNonRelativeIgnores() {
var ignore = Filter(base: root, pattern: "ab\\ ")
expect(ignore.disallows("ab ")).to(beTrue())
expect(ignore.disallows("ab")).to(beFalse())
ignore = Filter(base: self.root, pattern: "!include")
expect(ignore.explicitlyAllows("include")).to(beTrue())
expect(ignore.disallows("include")).to(beFalse())
expect(ignore.explicitlyAllows("no-include")).to(beFalse())
expect(ignore.disallows("no-include")).to(beFalse())
ignore = Filter(base: self.root, pattern: "a")
expect(ignore.disallows("a")).to(beTrue())
ignore = Filter(base: self.root, pattern: "*.png")
expect(ignore.disallows("a.png")).to(beTrue())
expect(ignore.disallows("b.png")).to(beTrue())
}
func testNonRelativeIgnoresUrl() {
var ignore = Filter(base: root, pattern: "ab\\ ")
expect(ignore.disallows(self.root.appendingPathComponent("ab "))).to(beTrue())
expect(ignore.explicitlyAllows(self.root.appendingPathComponent("ab"))).to(beFalse())
expect(ignore.disallows(self.root.appendingPathComponent("foo/bar/ab "))).to(beTrue())
expect(ignore.explicitlyAllows(self.root.appendingPathComponent("foo/bar/ab")))
.to(beFalse())
ignore = Filter(base: self.root, pattern: "!include")
expect(ignore.explicitlyAllows(self.root.appendingPathComponent("include"))).to(beTrue())
expect(ignore.disallows(self.root.appendingPathComponent("no-include"))).to(beFalse())
expect(ignore.explicitlyAllows(self.root.appendingPathComponent("foo/bar/include")))
.to(beTrue())
expect(ignore.disallows(self.root.appendingPathComponent("foo/bar/no-include")))
.to(beFalse())
ignore = Filter(base: self.root, pattern: "a")
expect(ignore.disallows(self.root.appendingPathComponent("a"))).to(beTrue())
expect(ignore.explicitlyAllows(self.root.appendingPathComponent("b"))).to(beFalse())
expect(ignore.disallows(self.root.appendingPathComponent("foo/bar/a"))).to(beTrue())
expect(ignore.explicitlyAllows(self.root.appendingPathComponent("foo/bar/b")))
.to(beFalse())
ignore = Filter(base: self.root, pattern: "*.png")
expect(ignore.disallows(self.root.appendingPathComponent("a.png"))).to(beTrue())
expect(ignore.disallows(self.root.appendingPathComponent("b.png"))).to(beTrue())
expect(ignore.explicitlyAllows(self.root.appendingPathComponent("c.jpg"))).to(beFalse())
expect(ignore.disallows(self.root.appendingPathComponent("foo/bar/a.png"))).to(beTrue())
expect(ignore.disallows(self.root.appendingPathComponent("foo/bar/b.png"))).to(beTrue())
expect(ignore.explicitlyAllows(self.root.appendingPathComponent("foo/bar/c.jpg")))
.to(beFalse())
}
func testRelativeIgnores() {
var ignore = Filter(base: root, pattern: "**/foo")
expect(ignore.disallows(self.root.appendingPathComponent("foo").path)).to(beTrue())
expect(ignore.disallows(self.root.appendingPathComponent("a/b/foo").path)).to(beTrue())
expect(ignore.explicitlyAllows(self.root.appendingPathComponent("a").path)).to(beFalse())
ignore = Filter(base: self.root, pattern: "abc/**")
expect(ignore.disallows(self.root.appendingPathComponent("abc/foo").path)).to(beTrue())
expect(ignore.disallows(self.root.appendingPathComponent("abc/def/foo").path))
.to(beTrue())
expect(ignore.explicitlyAllows(self.root.appendingPathComponent("a/b/c").path))
.to(beFalse())
ignore = Filter(base: self.root, pattern: "a/**/b")
expect(ignore.disallows(self.root.appendingPathComponent("a/b").path)).to(beTrue())
expect(ignore.disallows(self.root.appendingPathComponent("a/x/b").path)).to(beTrue())
expect(ignore.disallows(self.root.appendingPathComponent("a/x/y/b").path)).to(beTrue())
expect(ignore.explicitlyAllows(self.root.appendingPathComponent("a/x/y/c").path))
.to(beFalse())
}
func testRelativeIgnoresUrl() {
var ignore = Filter(base: root, pattern: "**/foo")
expect(ignore.disallows(self.root.appendingPathComponent("foo"))).to(beTrue())
expect(ignore.disallows(self.root.appendingPathComponent("a/b/foo"))).to(beTrue())
expect(ignore.explicitlyAllows(self.root.appendingPathComponent("a"))).to(beFalse())
ignore = Filter(base: self.root, pattern: "abc/**")
expect(ignore.disallows(self.root.appendingPathComponent("abc/foo"))).to(beTrue())
expect(ignore.disallows(self.root.appendingPathComponent("abc/def/foo")))
.to(beTrue())
expect(ignore.explicitlyAllows(self.root.appendingPathComponent("a/b/c"))).to(beFalse())
ignore = Filter(base: self.root, pattern: "a/**/b")
expect(ignore.disallows(self.root.appendingPathComponent("a/b"))).to(beTrue())
expect(ignore.disallows(self.root.appendingPathComponent("a/x/b"))).to(beTrue())
expect(ignore.disallows(self.root.appendingPathComponent("a/x/y/b"))).to(beTrue())
expect(ignore.explicitlyAllows(self.root.appendingPathComponent("a/x/y/c"))).to(beFalse())
}
}

View File

@ -0,0 +1,56 @@
/// Tae Won Ha - http://taewon.de - @hataewon
/// See LICENSE
@testable import Ignore
import Nimble
import XCTest
private struct IgnoreSplittingTestSpec {
var fileName: String
var mixed: [String]
var disallow: [String]
}
private let ignoreSplittingTestSpecs = [
IgnoreSplittingTestSpec(
fileName: "ignore-splitting-0",
mixed: [],
disallow: ["*.a", "*.b", "*.c", "*.d"]
),
IgnoreSplittingTestSpec(
fileName: "ignore-splitting-1",
mixed: ["*.a"],
disallow: ["*.b", "*.c", "*.d"]
),
IgnoreSplittingTestSpec(
fileName: "ignore-splitting-2",
mixed: ["*.a", "*.b"],
disallow: ["*.c", "*.d"]
),
IgnoreSplittingTestSpec(
fileName: "ignore-splitting-3",
mixed: ["*.a", "*.b", "*.c"],
disallow: ["*.d"]
),
IgnoreSplittingTestSpec(
fileName: "ignore-splitting-4",
mixed: ["*.a", "*.b", "*.c", "*.d"],
disallow: []
),
]
final class IgnoreSplitTest: XCTestCase {
func testIgnoreSplitting() {
ignoreSplittingTestSpecs.forEach { spec in
let url = Bundle.module.url(
forResource: "IgnoreCollectionTest",
withExtension: nil,
subdirectory: "Resources"
)!
let ignoreFile = Ignore(base: url, parent: nil, ignoreFileNames: [spec.fileName])!
expect(ignoreFile.mixedIgnores.map(\.pattern)).to(equal(spec.mixed))
expect(ignoreFile.remainingDisallowIgnores.map(\.pattern)).to(equal(spec.disallow))
}
}
}

View File

@ -0,0 +1,34 @@
/// Tae Won Ha - http://taewon.de - @hataewon
/// See LICENSE
@testable import Ignore
import Nimble
import XCTest
final class IgnoreTest: XCTestCase {
func testIgnoreSplitting() {
let root = Bundle.module.url(
forResource: "IgnoreCollectionTest",
withExtension: nil,
subdirectory: "Resources"
)!
let c = Ignore(base: root, parent: nil)!
expect(c.excludes(self.url("out", base: root, isDir: true))).to(beTrue())
expect(c.excludes(self.url("out", base: root, isDir: false))).to(beFalse())
expect(c.excludes(self.url("logs", base: root, isDir: true))).to(beTrue())
expect(c.excludes(self.url("logs", base: root, isDir: false))).to(beFalse())
expect(c.excludes(self.url("a.png", base: root))).to(beTrue())
expect(c.excludes(self.url("include-me", base: root))).to(beFalse())
expect(c.excludes(self.url("a/b/include-me", base: root))).to(beFalse())
expect(c.excludes(self.url("ignore-me", base: root))).to(beTrue())
expect(c.excludes(self.url("a/b/ignore-me", base: root))).to(beTrue())
}
private func url(_ path: String, base: URL, isDir: Bool = false) -> URL {
URL(fileURLWithPath: path, isDirectory: isDir, relativeTo: base)
}
}

View File

@ -0,0 +1,3 @@
0123
하태원
abcde

View File

@ -0,0 +1,3 @@
0123
하태원
abcde

View File

@ -0,0 +1,3 @@
0123
하태원
abcde

View File

@ -0,0 +1,3 @@
0123
하태원
abcde

View File

@ -0,0 +1,8 @@
*.png
# will be included below
include-me
vendor/
**/ignore-me

View File

@ -0,0 +1,5 @@
# include include-me file
!include-me
/logs/
/out/

View File

@ -0,0 +1,4 @@
*.a
*.b
*.c
*.d

View File

@ -0,0 +1,4 @@
!*.a
*.b
*.c
*.d

View File

@ -0,0 +1,4 @@
*.a
!*.b
*.c
*.d

View File

@ -0,0 +1,4 @@
!*.a
*.b
!*.c
*.d

View File

@ -0,0 +1,4 @@
*.a
*.b
*.c
!*.d

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2016 Tae Won Ha
Copyright (c) 2022 Tae Won Ha
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,4 +1,4 @@
// swift-tools-version:5.3
// swift-tools-version:5.6
import PackageDescription
@ -9,13 +9,9 @@ let package = Package(
.library(name: "NvimView", targets: ["NvimView"]),
],
dependencies: [
.package(
name: "MessagePack",
url: "https://github.com/a2/MessagePack.swift",
.upToNextMinor(from: "4.0.0")
),
.package(url: "https://github.com/ReactiveX/RxSwift", .upToNextMinor(from: "6.5.0")),
.package(url: "https://github.com/Quick/Nimble", .upToNextMinor(from: "9.2.1")),
.package(url: "https://github.com/a2/MessagePack.swift", from: "4.0.0"),
.package(url: "https://github.com/ReactiveX/RxSwift", from: "6.5.0"),
.package(url: "https://github.com/Quick/Nimble", from: "10.0.0"),
.package(name: "NvimServer", path: "../NvimServer"),
.package(name: "RxPack", path: "../RxPack"),
.package(name: "Commons", path: "../Commons"),
@ -29,7 +25,7 @@ let package = Package(
"RxPack",
"Tabs",
.product(name: "NvimServerTypes", package: "NvimServer"),
"MessagePack",
.product(name: "MessagePack", package: "MessagePack.swift"),
"Commons",
],
// com.qvacua.NvimView.vim is copied by the download NvimServer script.
@ -39,9 +35,6 @@ let package = Package(
.copy("Resources/NvimServer"),
]
),
.testTarget(
name: "NvimViewTests",
dependencies: ["NvimView", "Nimble"]
),
.testTarget(name: "NvimViewTests", dependencies: ["NvimView", "Nimble"]),
]
)

View File

@ -311,7 +311,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1200;
LastUpgradeCheck = 1330;
LastUpgradeCheck = 1340;
ORGANIZATIONNAME = "Tae Won Ha";
TargetAttributes = {
4B0225EF224AAE260052362B = {

View File

@ -53,7 +53,7 @@ git submodule update
xcode-select --install # install the Xcode command line tools, if you haven't already
brew bundle
code_sign=false use_carthage_cache=false download_deps=true ./bin/build_vimr.sh
code_sign=false use_carthage_cache=false ./bin/build_vimr.sh
# VimR.app will be placed in ./build/Build/Products/Release/
```

View File

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

View File

@ -1,4 +1,4 @@
// swift-tools-version:5.3
// swift-tools-version:5.6
import PackageDescription
@ -10,26 +10,16 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/ReactiveX/RxSwift", .upToNextMinor(from: "6.5.0")),
.package(
name: "MessagePack",
url: "https://github.com/a2/MessagePack.swift",
.upToNextMinor(from: "4.0.0")
),
.package(
name: "Socket",
url: "https://github.com/IBM-Swift/BlueSocket",
.upToNextMinor(from: "2.0.2")
),
.package(url: "https://github.com/Quick/Nimble", .upToNextMinor(from: "9.2.1")),
.package(url: "https://github.com/a2/MessagePack.swift", from: "4.0.0"),
.package(url: "https://github.com/IBM-Swift/BlueSocket", from: "2.0.2"),
.package(url: "https://github.com/Quick/Nimble", from: "10.0.0"),
],
targets: [
.target(
name: "RxPack",
dependencies: ["RxSwift", "MessagePack", "Socket"]
),
.testTarget(
name: "RxPackTests",
dependencies: ["RxPack", "Nimble"]
),
.target(name: "RxPack", dependencies: [
"RxSwift",
.product(name: "MessagePack", package: "MessagePack.swift"),
.product(name: "Socket", package: "BlueSocket"),
]),
.testTarget(name: "RxPackTests", dependencies: ["RxPack", "Nimble"]),
]
)

View File

@ -107,7 +107,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1020;
LastUpgradeCheck = 1330;
LastUpgradeCheck = 1340;
ORGANIZATIONNAME = "Tae Won Ha";
TargetAttributes = {
4B02265B224AB1490052362B = {

View File

@ -1,5 +1,4 @@
// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.
// swift-tools-version:5.6
import PackageDescription
@ -10,25 +9,17 @@ let package = Package(
.library(name: "Tabs", targets: ["Tabs"]),
],
dependencies: [
.package(
name: "MaterialIcons",
url: "https://github.com/qvacua/material-icons",
.upToNextMinor(from: "0.1.0")
),
.package(
name: "PureLayout",
url: "https://github.com/PureLayout/PureLayout",
.upToNextMinor(from: "3.1.9")
),
.package(url: "https://github.com/qvacua/material-icons", from: "0.1.0"),
.package(url: "https://github.com/PureLayout/PureLayout", from: "3.1.9"),
],
targets: [
.target(
name: "Tabs",
dependencies: ["PureLayout", "MaterialIcons"]
),
.testTarget(
name: "TabsTests",
dependencies: ["Tabs"]
dependencies: [
"PureLayout",
.product(name: "MaterialIcons", package: "material-icons"),
]
),
.testTarget(name: "TabsTests", dependencies: ["Tabs"]),
]
)

View File

@ -98,7 +98,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1220;
LastUpgradeCheck = 1330;
LastUpgradeCheck = 1340;
TargetAttributes = {
4BEBD4B5256A76BB002218F8 = {
CreatedOnToolsVersion = 12.2;

View File

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Ignore">
</FileRef>
<FileRef
location = "group:Commons">
</FileRef>

View File

@ -1,142 +1,158 @@
{
"object": {
"pins": [
{
"package": "Socket",
"repositoryURL": "https://github.com/IBM-Swift/BlueSocket",
"state": {
"branch": null,
"revision": "dd924c3bc2c1c144c42b8dda3896f1a03115ded4",
"version": "2.0.2"
}
},
{
"package": "CwlCatchException",
"repositoryURL": "https://github.com/mattgallagher/CwlCatchException.git",
"state": {
"branch": null,
"revision": "f809deb30dc5c9d9b78c872e553261a61177721a",
"version": "2.0.0"
}
},
{
"package": "CwlPreconditionTesting",
"repositoryURL": "https://github.com/mattgallagher/CwlPreconditionTesting.git",
"state": {
"branch": null,
"revision": "fb7a26374e8570ff5c68142e5c83406d6abae0d8",
"version": "2.0.2"
}
},
{
"package": "DictionaryCoding",
"repositoryURL": "https://github.com/elegantchaos/DictionaryCoding",
"state": {
"branch": null,
"revision": "ae19e456bd550fed8f341e5bae4318333c53a5b4",
"version": "1.0.9"
}
},
{
"package": "Down",
"repositoryURL": "https://github.com/johnxnguyen/Down",
"state": {
"branch": null,
"revision": "f34b166be1f1db4aa8f573067e901d72f2a6be57",
"version": "0.11.0"
}
},
{
"package": "EonilFSEvents",
"repositoryURL": "https://github.com/eonil/FSEvents",
"state": {
"branch": null,
"revision": "e6b7cdfa2754454e194a45ee6c2004d0f630fe88",
"version": "0.1.7"
}
},
{
"package": "MaterialIcons",
"repositoryURL": "https://github.com/qvacua/material-icons",
"state": {
"branch": null,
"revision": "c3db645060fd27df5f7e0a9873c2af22c280725e",
"version": "0.1.0"
}
},
{
"package": "MessagePack",
"repositoryURL": "https://github.com/a2/MessagePack.swift",
"state": {
"branch": null,
"revision": "27b35fd49e92fcae395bf8ccb233499d89cc7890",
"version": "4.0.0"
}
},
{
"package": "Nimble",
"repositoryURL": "https://github.com/Quick/Nimble",
"state": {
"branch": null,
"revision": "c93f16c25af5770f0d3e6af27c9634640946b068",
"version": "9.2.1"
}
},
{
"package": "PureLayout",
"repositoryURL": "https://github.com/PureLayout/PureLayout",
"state": {
"branch": null,
"revision": "5561683c96dc49b023c1299bfe4f6fbeed5f8199",
"version": "3.1.9"
}
},
{
"package": "RxSwift",
"repositoryURL": "https://github.com/ReactiveX/RxSwift",
"state": {
"branch": null,
"revision": "b4307ba0b6425c0ba4178e138799946c3da594f8",
"version": "6.5.0"
}
},
{
"package": "ShortcutRecorder",
"repositoryURL": "https://github.com/Kentzo/ShortcutRecorder",
"state": {
"branch": null,
"revision": "07b065085e172d85b7b5a0f3cc05f6ed47ad5af1",
"version": "3.3.0"
}
},
{
"package": "Sparkle",
"repositoryURL": "https://github.com/sparkle-project/Sparkle",
"state": {
"branch": null,
"revision": "286edd1fa22505a9e54d170e9fd07d775ea233f2",
"version": "2.1.0"
}
},
{
"package": "swift-argument-parser",
"repositoryURL": "https://github.com/apple/swift-argument-parser",
"state": {
"branch": null,
"revision": "6b2aa2748a7881eebb9f84fb10c01293e15b52ca",
"version": "0.5.0"
}
},
{
"package": "Swifter",
"repositoryURL": "https://github.com/httpswift/swifter",
"state": {
"branch": null,
"revision": "9483a5d459b45c3ffd059f7b55f9638e268632fd",
"version": "1.5.0"
}
"pins" : [
{
"identity" : "bluesocket",
"kind" : "remoteSourceControl",
"location" : "https://github.com/IBM-Swift/BlueSocket",
"state" : {
"revision" : "dd924c3bc2c1c144c42b8dda3896f1a03115ded4",
"version" : "2.0.2"
}
]
},
"version": 1
},
{
"identity" : "cwlcatchexception",
"kind" : "remoteSourceControl",
"location" : "https://github.com/mattgallagher/CwlCatchException.git",
"state" : {
"revision" : "f809deb30dc5c9d9b78c872e553261a61177721a",
"version" : "2.0.0"
}
},
{
"identity" : "cwlpreconditiontesting",
"kind" : "remoteSourceControl",
"location" : "https://github.com/mattgallagher/CwlPreconditionTesting.git",
"state" : {
"revision" : "c21f7bab5ca8eee0a9998bbd17ca1d0eb45d4688",
"version" : "2.1.0"
}
},
{
"identity" : "dictionarycoding",
"kind" : "remoteSourceControl",
"location" : "https://github.com/elegantchaos/DictionaryCoding",
"state" : {
"revision" : "ae19e456bd550fed8f341e5bae4318333c53a5b4",
"version" : "1.0.9"
}
},
{
"identity" : "down",
"kind" : "remoteSourceControl",
"location" : "https://github.com/johnxnguyen/Down",
"state" : {
"revision" : "f34b166be1f1db4aa8f573067e901d72f2a6be57",
"version" : "0.11.0"
}
},
{
"identity" : "fsevents",
"kind" : "remoteSourceControl",
"location" : "https://github.com/eonil/FSEvents",
"state" : {
"revision" : "e6b7cdfa2754454e194a45ee6c2004d0f630fe88",
"version" : "0.1.7"
}
},
{
"identity" : "material-icons",
"kind" : "remoteSourceControl",
"location" : "https://github.com/qvacua/material-icons",
"state" : {
"revision" : "c3db645060fd27df5f7e0a9873c2af22c280725e",
"version" : "0.1.0"
}
},
{
"identity" : "messagepack.swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/a2/MessagePack.swift",
"state" : {
"revision" : "27b35fd49e92fcae395bf8ccb233499d89cc7890",
"version" : "4.0.0"
}
},
{
"identity" : "misc.swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/qvacua/misc.swift",
"state" : {
"revision" : "e963af99e5eddc14b0f28c5c87a1f582c88bf128",
"version" : "0.0.1"
}
},
{
"identity" : "nimble",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Quick/Nimble",
"state" : {
"revision" : "1f3bde57bde12f5e7b07909848c071e9b73d6edc",
"version" : "10.0.0"
}
},
{
"identity" : "purelayout",
"kind" : "remoteSourceControl",
"location" : "https://github.com/PureLayout/PureLayout",
"state" : {
"revision" : "5561683c96dc49b023c1299bfe4f6fbeed5f8199",
"version" : "3.1.9"
}
},
{
"identity" : "rxswift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ReactiveX/RxSwift",
"state" : {
"revision" : "b4307ba0b6425c0ba4178e138799946c3da594f8",
"version" : "6.5.0"
}
},
{
"identity" : "shortcutrecorder",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Kentzo/ShortcutRecorder",
"state" : {
"revision" : "07b065085e172d85b7b5a0f3cc05f6ed47ad5af1",
"version" : "3.3.0"
}
},
{
"identity" : "sparkle",
"kind" : "remoteSourceControl",
"location" : "https://github.com/sparkle-project/Sparkle",
"state" : {
"revision" : "286edd1fa22505a9e54d170e9fd07d775ea233f2",
"version" : "2.1.0"
}
},
{
"identity" : "swift-argument-parser",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-argument-parser",
"state" : {
"revision" : "6b2aa2748a7881eebb9f84fb10c01293e15b52ca",
"version" : "0.5.0"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"revision" : "48254824bb4248676bf7ce56014ff57b142b77eb",
"version" : "1.0.2"
}
},
{
"identity" : "swifter",
"kind" : "remoteSourceControl",
"location" : "https://github.com/httpswift/swifter",
"state" : {
"revision" : "9483a5d459b45c3ffd059f7b55f9638e268632fd",
"version" : "1.5.0"
}
}
],
"version" : 2
}

View File

@ -24,7 +24,6 @@
1929B3A6C332FFAAEC7FD219 /* MainWindow+CustomTitle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B71B4BB6550F5BC6D4CF /* MainWindow+CustomTitle.swift */; };
1929B3AC66EFE35D68C020E3 /* MarkdownToolReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BFB0F294F3714D5E095F /* MarkdownToolReducer.swift */; };
1929B4219A68586E2CED6E96 /* FileMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B333D8752E2E68F35122 /* FileMonitor.swift */; };
1929B443B7AB2176A7818CA1 /* fuzzy_match.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1929B1B01340283D6AAD6B06 /* fuzzy_match.cc */; };
1929B4B00D7BB191A9A6532D /* HtmlPreviewToolReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BE5AEA3D0980860EED50 /* HtmlPreviewToolReducer.swift */; };
1929B4B70926DE113E6BF990 /* MarkdownPreviewReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BE37AA2843779CAFA76F /* MarkdownPreviewReducer.swift */; };
1929B4E54E2F13A7F5F2B682 /* BufferListReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B67A10E6BB2986B2416E /* BufferListReducer.swift */; };
@ -43,6 +42,7 @@
1929B6C0393DE40E34F4A49A /* ToolsPrefReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B694508FB5FDE607513A /* ToolsPrefReducer.swift */; };
1929B6D8F5FC723B7109031F /* OpenQuicklyReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B12CE56A9B36980288A4 /* OpenQuicklyReducer.swift */; };
1929B71381946860626E5224 /* FileBrowserReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BDC8F5D48578A90236E9 /* FileBrowserReducer.swift */; };
1929B7D1665BBB75DC89E391 /* IgnoreService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B71F6A82A34F16BB52BE /* IgnoreService.swift */; };
1929B805633C40EC1642121C /* RxCommons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B7609C0C23AC29BDC09B /* RxCommons.swift */; };
1929B8DDACEB28E6672AEC42 /* MainWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B6E01216D49BB9F3B6A3 /* MainWindow.swift */; };
1929B8F498D1E7C53F572CE2 /* KeysPref.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B14A5949FB64C4B2646F /* KeysPref.swift */; };
@ -70,7 +70,6 @@
1929BEDE1BE950EDA9497363 /* GeneralPref.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BB55946DAEBF55D24048 /* GeneralPref.swift */; };
1929BF03FD6465F289AA80B2 /* ToolsPref.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BB2AD21A10A0ECA66A5E /* ToolsPref.swift */; };
1929BF3253594E5B1908C6CE /* RpcAppearanceEpic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B230EE8F1428980988F0 /* RpcAppearanceEpic.swift */; };
1929BF5D0EFCC56A733BB4B7 /* FuzzySearch.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 1929B656C04BA6F950BFA2F5 /* FuzzySearch.xcdatamodel */; };
1929BFDE22D155F7C4B19E96 /* HtmlPreviewTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B85023B042C485409CE1 /* HtmlPreviewTool.swift */; };
4B029F1A1D45E349004EE0D3 /* PrefWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B029F1C1D45E349004EE0D3 /* PrefWindow.xib */; };
4B0B36202595236000B06899 /* Swifter in Frameworks */ = {isa = PBXBuildFile; productRef = 4BD5655224E8014100D52809 /* Swifter */; };
@ -155,17 +154,17 @@
4B94341620B95EC7005807BA /* MacVim-css.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4B9433DB20B95EC6005807BA /* MacVim-css.icns */; };
4B97E2CC1D33F53D00FC0660 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B97E2CE1D33F53D00FC0660 /* MainWindow.xib */; };
4B9D049D273481AD007E8614 /* Down in Frameworks */ = {isa = PBXBuildFile; productRef = 4B9D049C273481AD007E8614 /* Down */; };
4BA19812285B4BA600B49309 /* Misc in Frameworks */ = {isa = PBXBuildFile; productRef = 4BA19811285B4BA600B49309 /* Misc */; };
4BA19817285B599400B49309 /* FuzzySearch.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 1929B656C04BA6F950BFA2F5 /* FuzzySearch.xcdatamodel */; };
4BADD55B283A847100C6B16D /* Ignore in Frameworks */ = {isa = PBXBuildFile; productRef = 4BADD55A283A847100C6B16D /* Ignore */; };
4BADD55E283ABD0200C6B16D /* OrderedCollections in Frameworks */ = {isa = PBXBuildFile; productRef = 4BADD55D283ABD0200C6B16D /* OrderedCollections */; };
4BB409E51DD68CCC005F39A2 /* FileBrowserMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BB409E71DD68CCC005F39A2 /* FileBrowserMenu.xib */; };
4BDF50171D77540900D8FBC3 /* OpenQuicklyWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BDF50191D77540900D8FBC3 /* OpenQuicklyWindow.xib */; };
4BEBA5091CFF374B00673FDF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBA5081CFF374B00673FDF /* AppDelegate.swift */; };
4BEBA50B1CFF374B00673FDF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4BEBA50A1CFF374B00673FDF /* Assets.xcassets */; };
4BEBA50E1CFF374B00673FDF /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BEBA50C1CFF374B00673FDF /* MainMenu.xib */; };
4BF07EE41D51326A009BECEB /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 4BF07EE61D51326A009BECEB /* Credits.rtf */; };
4BF70EC423D1B3F9009E51E9 /* FuzzyMatcher.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BF70EBF23D1B3F9009E51E9 /* FuzzyMatcher.mm */; };
4BF70EC823D1B3F9009E51E9 /* FuzzyMatcherPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF70EC323D1B3F9009E51E9 /* FuzzyMatcherPool.swift */; };
4BF70ED223D1B4AF009E51E9 /* FoundationCommons.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BF70ED123D1B4AF009E51E9 /* FoundationCommons.m */; };
4BF70ED623D1B54F009E51E9 /* ScoredUrl.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BF70ED523D1B54F009E51E9 /* ScoredUrl.m */; };
4BF70EE123D1B5B3009E51E9 /* FileScanBaton.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BF70EDF23D1B5B3009E51E9 /* FileScanBaton.m */; };
4BF70EE523D1B5EC009E51E9 /* FuzzySearchService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF70EE323D1B5EC009E51E9 /* FuzzySearchService.swift */; };
4BF70EEA23D1B5FF009E51E9 /* CoreDataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF70EE923D1B5FF009E51E9 /* CoreDataStack.swift */; };
/* End PBXBuildFile section */
@ -196,17 +195,13 @@
1929B067B3247675BCD09218 /* MainWindow+Actions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MainWindow+Actions.swift"; sourceTree = "<group>"; };
1929B07A4A9209C88380E015 /* PrefPane.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrefPane.swift; sourceTree = "<group>"; };
1929B07F0085B7AE10413346 /* ShortcutsTableSubviews.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShortcutsTableSubviews.swift; sourceTree = "<group>"; };
1929B0E63986F95E2F8DFF21 /* FileItem+CoreDataClass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FileItem+CoreDataClass.h"; sourceTree = "<group>"; };
1929B0E9B2F018D3E31D4B0B /* ShortcutsPref.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShortcutsPref.swift; sourceTree = "<group>"; };
1929B0EB3F49C42A57D083AF /* GeneralPrefReducer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneralPrefReducer.swift; sourceTree = "<group>"; };
1929B0FBFB766042CF06E463 /* AppearancePref.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppearancePref.swift; sourceTree = "<group>"; };
1929B12CE56A9B36980288A4 /* OpenQuicklyReducer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpenQuicklyReducer.swift; sourceTree = "<group>"; };
1929B14A5949FB64C4B2646F /* KeysPref.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeysPref.swift; sourceTree = "<group>"; };
1929B1534B8857C519D7C0FB /* FileItem+CoreDataProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FileItem+CoreDataProperties.h"; sourceTree = "<group>"; };
1929B1558455B3A74D93EF2A /* OpenQuicklyFileViewRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpenQuicklyFileViewRow.swift; sourceTree = "<group>"; };
1929B17B1BC7CA08DC76495C /* FileItem+CoreDataProperties.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "FileItem+CoreDataProperties.m"; sourceTree = "<group>"; };
1929B18E9BE35750BF2BA571 /* HtmlPreviewMiddleware.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HtmlPreviewMiddleware.swift; sourceTree = "<group>"; };
1929B1B01340283D6AAD6B06 /* fuzzy_match.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = fuzzy_match.cc; path = FuzzyMatcher/fuzzy_match.cc; sourceTree = "<group>"; };
1929B1DC584C89C477E83FA2 /* HttpServerMiddleware.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HttpServerMiddleware.swift; sourceTree = "<group>"; };
1929B230EE8F1428980988F0 /* RpcAppearanceEpic.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RpcAppearanceEpic.swift; sourceTree = "<group>"; };
1929B333D8752E2E68F35122 /* FileMonitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileMonitor.swift; sourceTree = "<group>"; };
@ -218,7 +213,6 @@
1929B617C229B19DB3E987B8 /* MarkdownPreviewMiddleware.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarkdownPreviewMiddleware.swift; sourceTree = "<group>"; };
1929B656C04BA6F950BFA2F5 /* FuzzySearch.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = FuzzySearch.xcdatamodel; sourceTree = "<group>"; };
1929B66A5E2D00EA143AFD86 /* RxRedux.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxRedux.swift; sourceTree = "<group>"; };
1929B672CE187B4D3EA1D3EE /* fuzzy_match.hh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = fuzzy_match.hh; path = FuzzyMatcher/fuzzy_match.hh; sourceTree = "<group>"; };
1929B67A10E6BB2986B2416E /* BufferListReducer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BufferListReducer.swift; sourceTree = "<group>"; };
1929B694508FB5FDE607513A /* ToolsPrefReducer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ToolsPrefReducer.swift; sourceTree = "<group>"; };
1929B6AD3396160AA2C46919 /* Debouncer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Debouncer.swift; sourceTree = "<group>"; };
@ -229,6 +223,7 @@
1929B714EB137AE448CE8ABD /* MainWindow+Delegates.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MainWindow+Delegates.swift"; sourceTree = "<group>"; };
1929B71A92C24FEFE79A851E /* OpenQuicklyWindow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpenQuicklyWindow.swift; sourceTree = "<group>"; };
1929B71B4BB6550F5BC6D4CF /* MainWindow+CustomTitle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MainWindow+CustomTitle.swift"; sourceTree = "<group>"; };
1929B71F6A82A34F16BB52BE /* IgnoreService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IgnoreService.swift; sourceTree = "<group>"; };
1929B7609C0C23AC29BDC09B /* RxCommons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCommons.swift; sourceTree = "<group>"; };
1929B7A68B7109CEFAF105E8 /* AppDelegateReducer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegateReducer.swift; sourceTree = "<group>"; };
1929B7F7A4B3FD52263D211D /* Defs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Defs.swift; sourceTree = "<group>"; };
@ -236,7 +231,6 @@
1929B85023B042C485409CE1 /* HtmlPreviewTool.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HtmlPreviewTool.swift; sourceTree = "<group>"; };
1929B88B5FA08E897A3C2168 /* KeysPrefReducer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeysPrefReducer.swift; sourceTree = "<group>"; };
1929B93256AF7F9137223E36 /* DefaultShortcuts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefaultShortcuts.swift; sourceTree = "<group>"; };
1929B98192F6873508F8D76A /* FileItem+CoreDataClass.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "FileItem+CoreDataClass.m"; sourceTree = "<group>"; };
1929B9AF20D7BD6E5C975128 /* FoundationCommons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoundationCommons.swift; sourceTree = "<group>"; };
1929BA05F1FE30CA74F006C4 /* CssUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CssUtils.swift; sourceTree = "<group>"; };
1929BA43449BA41666CD55ED /* BufferList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BufferList.swift; sourceTree = "<group>"; };
@ -342,16 +336,8 @@
4BEBA5141CFF374B00673FDF /* VimRTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VimRTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
4BEBA51A1CFF374B00673FDF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
4BF07EE51D51326A009BECEB /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = Base; path = Base.lproj/Credits.rtf; sourceTree = "<group>"; };
4BF18C371FD2E2AB00DF95D1 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = ../Carthage/Build/Mac/Sparkle.framework; sourceTree = "<group>"; };
4BF70EBF23D1B3F9009E51E9 /* FuzzyMatcher.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = FuzzyMatcher.mm; path = FuzzyMatcher/FuzzyMatcher.mm; sourceTree = "<group>"; };
4BF70EC123D1B3F9009E51E9 /* FuzzyMatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FuzzyMatcher.h; path = FuzzyMatcher/FuzzyMatcher.h; sourceTree = "<group>"; };
4BF70EC323D1B3F9009E51E9 /* FuzzyMatcherPool.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FuzzyMatcherPool.swift; path = FuzzyMatcher/FuzzyMatcherPool.swift; sourceTree = "<group>"; };
4BF70ED023D1B4AF009E51E9 /* FoundationCommons.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FoundationCommons.h; sourceTree = "<group>"; };
4BF70ED123D1B4AF009E51E9 /* FoundationCommons.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FoundationCommons.m; sourceTree = "<group>"; };
4BF70ED423D1B54F009E51E9 /* ScoredUrl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScoredUrl.h; sourceTree = "<group>"; };
4BF70ED523D1B54F009E51E9 /* ScoredUrl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScoredUrl.m; sourceTree = "<group>"; };
4BF70EDF23D1B5B3009E51E9 /* FileScanBaton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileScanBaton.m; sourceTree = "<group>"; };
4BF70EE023D1B5B3009E51E9 /* FileScanBaton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileScanBaton.h; sourceTree = "<group>"; };
4BF70EE323D1B5EC009E51E9 /* FuzzySearchService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FuzzySearchService.swift; sourceTree = "<group>"; };
4BF70EE923D1B5FF009E51E9 /* CoreDataStack.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataStack.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -361,9 +347,11 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4BA19812285B4BA600B49309 /* Misc in Frameworks */,
4B0B362A2595236000B06899 /* ShortcutRecorder in Frameworks */,
4B0B36242595236000B06899 /* EonilFSEvents in Frameworks */,
4B9D049D273481AD007E8614 /* Down in Frameworks */,
4BADD55E283ABD0200C6B16D /* OrderedCollections in Frameworks */,
4B6C6AE5267C71ED00F77527 /* RxRelay in Frameworks */,
4B0B36212595236000B06899 /* PureLayout in Frameworks */,
4B6C6AE3267C71ED00F77527 /* RxCocoa in Frameworks */,
@ -371,6 +359,7 @@
4B0B362C2595236000B06899 /* Commons in Frameworks */,
4B0B36202595236000B06899 /* Swifter in Frameworks */,
4B0B362F2595236000B06899 /* Sparkle in Frameworks */,
4BADD55B283A847100C6B16D /* Ignore in Frameworks */,
4B0B36232595236000B06899 /* DictionaryCoding in Frameworks */,
4B0B362D2595236000B06899 /* MaterialIcons in Frameworks */,
4B6C6AE7267C71ED00F77527 /* RxSwift in Frameworks */,
@ -453,18 +442,6 @@
name = Commons;
sourceTree = "<group>";
};
1929BA1E1547FE22A342BFD4 /* Core Data */ = {
isa = PBXGroup;
children = (
1929B17B1BC7CA08DC76495C /* FileItem+CoreDataProperties.m */,
1929B1534B8857C519D7C0FB /* FileItem+CoreDataProperties.h */,
1929B98192F6873508F8D76A /* FileItem+CoreDataClass.m */,
1929B0E63986F95E2F8DFF21 /* FileItem+CoreDataClass.h */,
1929B656C04BA6F950BFA2F5 /* FuzzySearch.xcdatamodel */,
);
name = "Core Data";
sourceTree = "<group>";
};
1929BA652D3B88FC071531EC /* UI */ = {
isa = PBXGroup;
children = (
@ -480,15 +457,6 @@
name = UI;
sourceTree = "<group>";
};
1929BAD7FC1CCB6E95D6C098 /* ccls */ = {
isa = PBXGroup;
children = (
1929B1B01340283D6AAD6B06 /* fuzzy_match.cc */,
1929B672CE187B4D3EA1D3EE /* fuzzy_match.hh */,
);
name = ccls;
sourceTree = "<group>";
};
1929BB4CF1C1FFEE6CCDD6FD /* Preferences */ = {
isa = PBXGroup;
children = (
@ -558,14 +526,6 @@
name = Middlewares;
sourceTree = "<group>";
};
4B5012001EBA791000F76C46 /* Frameworks */ = {
isa = PBXGroup;
children = (
4BF18C371FD2E2AB00DF95D1 /* Sparkle.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
4B8C64D023F024D9008733D8 /* Build configurations */ = {
isa = PBXGroup;
children = (
@ -661,11 +621,16 @@
name = resources;
sourceTree = "<group>";
};
4BADD559283A847100C6B16D /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
4BDF50101D760AB700D8FBC3 /* Commons */ = {
isa = PBXGroup;
children = (
4BF70ED023D1B4AF009E51E9 /* FoundationCommons.h */,
4BF70ED123D1B4AF009E51E9 /* FoundationCommons.m */,
4B6A70931D60E04200E12030 /* AppKitCommons.swift */,
1929B9AF20D7BD6E5C975128 /* FoundationCommons.swift */,
1929B7609C0C23AC29BDC09B /* RxCommons.swift */,
@ -679,8 +644,8 @@
4B8C64D023F024D9008733D8 /* Build configurations */,
4BEBA5071CFF374B00673FDF /* VimR */,
4BEBA5171CFF374B00673FDF /* VimRTests */,
4B5012001EBA791000F76C46 /* Frameworks */,
4BEBA5061CFF374B00673FDF /* Products */,
4BADD559283A847100C6B16D /* Frameworks */,
);
indentWidth = 2;
sourceTree = "<group>";
@ -725,17 +690,12 @@
4BF70ECB23D1B40A009E51E9 /* Fuzzy Search */ = {
isa = PBXGroup;
children = (
1929B656C04BA6F950BFA2F5 /* FuzzySearch.xcdatamodel */,
4BF70EE923D1B5FF009E51E9 /* CoreDataStack.swift */,
4BF70EE323D1B5EC009E51E9 /* FuzzySearchService.swift */,
4BF70ED423D1B54F009E51E9 /* ScoredUrl.h */,
4BF70ED523D1B54F009E51E9 /* ScoredUrl.m */,
4BF70EC123D1B3F9009E51E9 /* FuzzyMatcher.h */,
4BF70EBF23D1B3F9009E51E9 /* FuzzyMatcher.mm */,
4BF70EC323D1B3F9009E51E9 /* FuzzyMatcherPool.swift */,
4BF70EE023D1B5B3009E51E9 /* FileScanBaton.h */,
4BF70EDF23D1B5B3009E51E9 /* FileScanBaton.m */,
1929BAD7FC1CCB6E95D6C098 /* ccls */,
1929BA1E1547FE22A342BFD4 /* Core Data */,
1929B71F6A82A34F16BB52BE /* IgnoreService.swift */,
);
name = "Fuzzy Search";
sourceTree = "<group>";
@ -785,6 +745,9 @@
4B6C6AE4267C71ED00F77527 /* RxRelay */,
4B6C6AE6267C71ED00F77527 /* RxSwift */,
4B9D049C273481AD007E8614 /* Down */,
4BADD55A283A847100C6B16D /* Ignore */,
4BADD55D283ABD0200C6B16D /* OrderedCollections */,
4BA19811285B4BA600B49309 /* Misc */,
);
productName = VimR;
productReference = 4BEBA5051CFF374B00673FDF /* VimR-dev.app */;
@ -820,7 +783,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0830;
LastUpgradeCheck = 1330;
LastUpgradeCheck = 1340;
ORGANIZATIONNAME = "Tae Won Ha";
TargetAttributes = {
4BEBA5041CFF374B00673FDF = {
@ -856,6 +819,8 @@
4BD67CD824EE45CA00147C51 /* XCRemoteSwiftPackageReference "Nimble" */,
4BA284B0256471ED00CFDF7F /* XCRemoteSwiftPackageReference "Sparkle" */,
4B9D049B273481AD007E8614 /* XCRemoteSwiftPackageReference "Down" */,
4BADD55C283ABD0200C6B16D /* XCRemoteSwiftPackageReference "swift-collections" */,
4BA19810285B4BA600B49309 /* XCRemoteSwiftPackageReference "misc" */,
);
productRefGroup = 4BEBA5061CFF374B00673FDF /* Products */;
projectDirPath = "";
@ -975,6 +940,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4BA19817285B599400B49309 /* FuzzySearch.xcdatamodel in Sources */,
4B238BE11D3BF24200CBDD98 /* Application.swift in Sources */,
4B6A70941D60E04200E12030 /* AppKitCommons.swift in Sources */,
4BEBA5091CFF374B00673FDF /* AppDelegate.swift in Sources */,
@ -986,7 +952,6 @@
1929B29B95AD176D57942E08 /* UiRootReducer.swift in Sources */,
1929BB4A9B2FA42A64CCCC76 /* MainWindowReducer.swift in Sources */,
4BF70ED623D1B54F009E51E9 /* ScoredUrl.m in Sources */,
4BF70EC823D1B3F9009E51E9 /* FuzzyMatcherPool.swift in Sources */,
1929B8FB248D71BF88A35761 /* MarkdownTool.swift in Sources */,
1929B4B70926DE113E6BF990 /* MarkdownPreviewReducer.swift in Sources */,
1929B5C1BABBC0D09D97C3EF /* MarkdownPreviewMiddleware.swift in Sources */,
@ -994,7 +959,6 @@
1929B3AC66EFE35D68C020E3 /* MarkdownToolReducer.swift in Sources */,
1929B59FA5C286E010F70BEE /* Types.swift in Sources */,
1929B6D8F5FC723B7109031F /* OpenQuicklyReducer.swift in Sources */,
4BF70EE123D1B5B3009E51E9 /* FileScanBaton.m in Sources */,
1929B71381946860626E5224 /* FileBrowserReducer.swift in Sources */,
1929BA715337FE26155B2071 /* BufferList.swift in Sources */,
1929B4E54E2F13A7F5F2B682 /* BufferListReducer.swift in Sources */,
@ -1015,12 +979,10 @@
1929BA76A1D97D8226F7CFB1 /* Debouncer.swift in Sources */,
1929BFDE22D155F7C4B19E96 /* HtmlPreviewTool.swift in Sources */,
1929B4B00D7BB191A9A6532D /* HtmlPreviewToolReducer.swift in Sources */,
4BF70ED223D1B4AF009E51E9 /* FoundationCommons.m in Sources */,
1929BCF7F7B9CC5499A3F506 /* AdvancedPrefReducer.swift in Sources */,
1929BF03FD6465F289AA80B2 /* ToolsPref.swift in Sources */,
1929B6C0393DE40E34F4A49A /* ToolsPrefReducer.swift in Sources */,
1929B542A071BD03C846F6EF /* PrefUtils.swift in Sources */,
4BF70EC423D1B3F9009E51E9 /* FuzzyMatcher.mm in Sources */,
1929BE2F3E0182CC51F2763A /* ThemedTableSubviews.swift in Sources */,
1929B6460862447A31B5B082 /* ImageAndTextTableCell.swift in Sources */,
1929BBE28654E4307AF1E2FD /* Theme.swift in Sources */,
@ -1040,14 +1002,13 @@
1929BF3253594E5B1908C6CE /* RpcAppearanceEpic.swift in Sources */,
1929B5A0EDD1119CFF7BB84C /* Defs.swift in Sources */,
1929B376DB09AB5FDBF42BA1 /* MainWindow+Types.swift in Sources */,
1929B443B7AB2176A7818CA1 /* fuzzy_match.cc in Sources */,
1929BF5D0EFCC56A733BB4B7 /* FuzzySearch.xcdatamodel in Sources */,
1929B4219A68586E2CED6E96 /* FileMonitor.swift in Sources */,
1929B223C6E97C090474B2C2 /* Resources.swift in Sources */,
1929BC64D3C195A92BE3FD64 /* HtmlPreviewMiddleware.swift in Sources */,
1929B29FF537A339CF4075BD /* CssUtils.swift in Sources */,
1929B805633C40EC1642121C /* RxCommons.swift in Sources */,
1929B28EF1D4135A94C07558 /* ShortcutService.swift in Sources */,
1929B7D1665BBB75DC89E391 /* IgnoreService.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1153,7 +1114,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 20220419.180005;
CURRENT_PROJECT_VERSION = 20220616.153112;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
@ -1214,7 +1175,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 20220419.180005;
CURRENT_PROJECT_VERSION = 20220616.153112;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@ -1243,21 +1204,15 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 20220419.180005;
CURRENT_PROJECT_VERSION = 20220616.153112;
DEFINES_MODULE = YES;
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/.deps/include";
IBC_MODULE = VimR;
INFOPLIST_FILE = VimR/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
OTHER_LDFLAGS = (
"$(PROJECT_DIR)/.deps/lib/liblzma.a",
"$(PROJECT_DIR)/.deps/lib/libpcre.a",
"$(PROJECT_DIR)/.deps/lib/libag.a",
"-pthread",
);
OTHER_LDFLAGS = "-pthread";
PRODUCT_BUNDLE_IDENTIFIER = "$(VIMR_BUNDLE_IDENTIFIER)";
PRODUCT_MODULE_NAME = VimR;
PRODUCT_NAME = "$(VIMR_DISPLAY_NAME)";
@ -1271,21 +1226,15 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 20220419.180005;
CURRENT_PROJECT_VERSION = 20220616.153112;
DEFINES_MODULE = YES;
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/.deps/include";
IBC_MODULE = VimR;
INFOPLIST_FILE = VimR/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
OTHER_LDFLAGS = (
"$(PROJECT_DIR)/.deps/lib/liblzma.a",
"$(PROJECT_DIR)/.deps/lib/libpcre.a",
"$(PROJECT_DIR)/.deps/lib/libag.a",
"-pthread",
);
OTHER_LDFLAGS = "-pthread";
PRODUCT_BUNDLE_IDENTIFIER = "$(VIMR_BUNDLE_IDENTIFIER)";
PRODUCT_MODULE_NAME = VimR;
PRODUCT_NAME = "$(VIMR_DISPLAY_NAME)";
@ -1408,6 +1357,14 @@
version = 0.11.0;
};
};
4BA19810285B4BA600B49309 /* XCRemoteSwiftPackageReference "misc" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/qvacua/misc.swift";
requirement = {
kind = exactVersion;
version = 0.0.1;
};
};
4BA284B0256471ED00CFDF7F /* XCRemoteSwiftPackageReference "Sparkle" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/sparkle-project/Sparkle";
@ -1416,6 +1373,14 @@
version = 2.1.0;
};
};
4BADD55C283ABD0200C6B16D /* XCRemoteSwiftPackageReference "swift-collections" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/apple/swift-collections.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 1.0.0;
};
};
4BD5655124E8014100D52809 /* XCRemoteSwiftPackageReference "swifter" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/httpswift/swifter";
@ -1453,7 +1418,7 @@
repositoryURL = "https://github.com/Quick/Nimble";
requirement = {
kind = upToNextMinorVersion;
minimumVersion = 9.2.1;
minimumVersion = 10.0.0;
};
};
/* End XCRemoteSwiftPackageReference section */
@ -1502,11 +1467,25 @@
package = 4B9D049B273481AD007E8614 /* XCRemoteSwiftPackageReference "Down" */;
productName = Down;
};
4BA19811285B4BA600B49309 /* Misc */ = {
isa = XCSwiftPackageProductDependency;
package = 4BA19810285B4BA600B49309 /* XCRemoteSwiftPackageReference "misc" */;
productName = Misc;
};
4BA284B1256471ED00CFDF7F /* Sparkle */ = {
isa = XCSwiftPackageProductDependency;
package = 4BA284B0256471ED00CFDF7F /* XCRemoteSwiftPackageReference "Sparkle" */;
productName = Sparkle;
};
4BADD55A283A847100C6B16D /* Ignore */ = {
isa = XCSwiftPackageProductDependency;
productName = Ignore;
};
4BADD55D283ABD0200C6B16D /* OrderedCollections */ = {
isa = XCSwiftPackageProductDependency;
package = 4BADD55C283ABD0200C6B16D /* XCRemoteSwiftPackageReference "swift-collections" */;
productName = OrderedCollections;
};
4BD5655224E8014100D52809 /* Swifter */ = {
isa = XCSwiftPackageProductDependency;
package = 4BD5655124E8014100D52809 /* XCRemoteSwiftPackageReference "swifter" */;

View File

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

View File

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

View File

@ -1,15 +1,12 @@
{\rtf1\ansi\ansicpg1252\cocoartf2513
{\rtf1\ansi\ansicpg1252\cocoartf2638
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;}
\paperw11900\paperh16840\vieww10960\viewh15520\viewkind0
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0
{\field{\*\fldinst{HYPERLINK "http://vimr.org"}}{\fldrslt
\f0\fs24 \cf0 http://vimr.org}}
\f0\fs24 \
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0
{\field{\*\fldinst{HYPERLINK "https://github.com/qvacua/vimr"}}{\fldrslt \cf0 https://github.com/qvacua/vimr}}
\f1\b \
{\field{\*\fldinst{HYPERLINK "https://github.com/qvacua/vimr"}}{\fldrslt
\f0\fs24 \cf0 https://github.com/qvacua/vimr}}
\f1\b\fs24 \
\
By:
\f0\b0 \
@ -34,6 +31,7 @@ By:
\f1\b Backers
\f0\b0 \
{\field{\*\fldinst{HYPERLINK "https://github.com/qvacua/"}}{\fldrslt https://github.com/qvacua/}}\
{\field{\*\fldinst{HYPERLINK "https://www.bountysource.com/teams/vimr/backers"}}{\fldrslt https://www.bountysource.com/teams/vimr/backers}}\
\
@ -106,16 +104,17 @@ By:
{\field{\*\fldinst{HYPERLINK "https://github.com/Kentzo/ShortcutRecorder"}}{\fldrslt https://github.com/Kentzo/ShortcutRecorder}}\
\
\f1\b ccls\
{\field{\*\fldinst{HYPERLINK "https://github.com/MaskRay/ccls"}}{\fldrslt
\f0\b0 https://github.com/MaskRay/ccls}}
\f0\b0 \
\f1\b wildmatch\
\f0\b0 {\field{\*\fldinst{HYPERLINK "https://github.com/davvid/wildmatch"}}{\fldrslt https://github.com/davvid/wildmatch}}\
via {\field{\*\fldinst{HYPERLINK "https://github.com/qvacua/misc.swift"}}{\fldrslt https://github.com/qvacua/misc.swift}}\
\
\f1\b The Silver Searcher\
{\field{\*\fldinst{HYPERLINK "https://github.com/ggreer/the_silver_searcher"}}{\fldrslt
\f0\b0 https://github.com/ggreer/the_silver_searcher}}
\f1\b fzy\
{\field{\*\fldinst{HYPERLINK "https://github.com/jhawthorn/fzy"}}{\fldrslt
\f0\b0 https://github.com/jhawthorn/fzy}}
\f0\b0 \
via {\field{\*\fldinst{HYPERLINK "https://github.com/qvacua/misc.swift"}}{\fldrslt https://github.com/qvacua/misc.swift}}\
\
\f1\b Nimble

View File

@ -3,8 +3,5 @@
* See LICENSE
*/
#import "FuzzyMatcher.h"
#import "FoundationCommons.h"
#import "ScoredUrl.h"
#import "FileScanBaton.h"
#import "FileItem+CoreDataProperties.h"

View File

@ -62,7 +62,7 @@ class CoreDataStack {
guard fileManager.fileExists(atPath: path) else { throw Error.pathDoesNotExit }
let parentFolder = URL(fileURLWithPath: path)
guard parentFolder.isDir else { throw Error.pathNotFolder }
guard parentFolder.hasDirectoryPath else { throw Error.pathNotFolder }
url = parentFolder.appendingPathComponent(modelName)
}

View File

@ -1,39 +0,0 @@
//
// FileItem+CoreDataProperties.h
// VimR
//
// Created by Tae Won Ha on 18.01.20.
// Copyright © 2020 Tae Won Ha. All rights reserved.
//
//
#import "FileItem+CoreDataClass.h"
NS_ASSUME_NONNULL_BEGIN
@interface FileItem (CoreDataProperties)
+ (NSFetchRequest<FileItem *> *)fetchRequest;
@property (nonatomic) int16_t direntType;
@property (nonatomic) BOOL isHidden;
@property (nonatomic) BOOL isPackage;
@property (nonatomic) BOOL needsScanChildren;
@property (nullable, nonatomic, copy) NSString *pathStart;
@property (nullable, nonatomic, copy) NSURL *url;
@property (nullable, nonatomic, retain) NSSet<FileItem *> *children;
@property (nullable, nonatomic, retain) FileItem *parent;
@end
@interface FileItem (CoreDataGeneratedAccessors)
- (void)addChildrenObject:(FileItem *)value;
- (void)removeChildrenObject:(FileItem *)value;
- (void)addChildren:(NSSet<FileItem *> *)values;
- (void)removeChildren:(NSSet<FileItem *> *)values;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,27 +0,0 @@
//
// FileItem+CoreDataProperties.m
// VimR
//
// Created by Tae Won Ha on 18.01.20.
// Copyright © 2020 Tae Won Ha. All rights reserved.
//
//
#import "FileItem+CoreDataProperties.h"
@implementation FileItem (CoreDataProperties)
+ (NSFetchRequest<FileItem *> *)fetchRequest {
return [NSFetchRequest fetchRequestWithEntityName:@"FileItem"];
}
@dynamic direntType;
@dynamic isHidden;
@dynamic isPackage;
@dynamic needsScanChildren;
@dynamic pathStart;
@dynamic url;
@dynamic children;
@dynamic parent;
@end

View File

@ -386,7 +386,7 @@ extension FileOutlineView {
@IBAction func setAsWorkingDirectory(_: Any?) {
guard let node = self.node(from: self.clickedItem) else { return }
guard node.url.isDir else { return }
guard node.url.hasDirectoryPath else { return }
self.emit(UuidAction(uuid: self.uuid, action: .setAsWorkingDirectory(node.url)))
}
@ -461,7 +461,7 @@ 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.isDir }
if item.action == #selector(self.setAsWorkingDirectory(_:)) { return clickedNode.url.hasDirectoryPath }
return true
}
@ -483,7 +483,7 @@ extension FileOutlineView {
switch char {
case " ", "\r": // Why "\r" and not "\n"?
if node.url.isDir || node.url.isPackage {
if node.url.hasDirectoryPath || node.url.isPackage {
self.toggle(item: node)
} else {
self.emit(UuidAction(uuid: self.uuid, action: .open(url: node.url, mode: .newTab)))
@ -515,7 +515,7 @@ class Node: NSObject, Comparable {
init(url: URL) {
self.url = url
self.isLeaf = !url.isDir
self.isLeaf = !url.hasDirectoryPath
self.isHidden = url.isHidden
}
}

View File

@ -1,23 +0,0 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
#import <Foundation/Foundation.h>
#import "ignore.h"
#import "scandir.h"
@interface FileScanBaton : NSObject
@property(readonly, nonnull) ignores *ig;
@property(readonly, nonnull) NSString *pathStart;
@property(readonly, nonnull) NSURL *url;
- (bool)test:(NSURL * _Nonnull)url;
- (instancetype _Nonnull)initWithBaseUrl:(NSURL *_Nonnull)baseUrl;
- (instancetype _Nonnull)initWithParent:(FileScanBaton *_Nonnull)parent url:(NSURL *_Nonnull)url;
@end

View File

@ -1,205 +0,0 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
#import "FileScanBaton.h"
#import "util.h"
#import "FoundationCommons.h"
#ifdef DEBUG
FILE *out_fd;
static dispatch_once_t debugToken;
#endif
@implementation FileScanBaton {
NSURL *_baseUrl;
scandir_baton_t *_baton;
const char *_basePathCstr;
const char *_pathStartCstr;
}
static const char *cfstr_to_cstr_copy(CFStringRef cfstr);
static void load_global_gitignores(ignores *ig);
- (bool)test:(NSURL *_Nonnull)url {
struct dirent dirent = url.fakeDirent;
return (bool) filename_filter(_baton->path_start, &dirent, _baton);
}
- (instancetype)initWithBaseUrl:(NSURL *)baseUrl {
#ifdef DEBUG
dispatch_once(&debugToken, ^{
out_fd = fopen("/Users/hat/Downloads/scan.log", "w");
set_log_level(LOG_LEVEL_DEBUG);
});
#endif
self = [super init];
if (self == nil) { return nil; }
_baseUrl = baseUrl;
_url = baseUrl;
_pathStart = @".";
_ig = init_ignore([FileScanBaton stubBatonWithGlobalGitignores].ig, "", 0);
[self initScanDirBaton];
[self loadVcsIgnores];
return self;
}
- (instancetype)initWithParent:(FileScanBaton *)parent url:(NSURL *)url {
self = [super init];
if (self == nil) { return nil; }
_baseUrl = parent.url;
_url = url;
_pathStart = [parent.pathStart stringByAppendingFormat:@"/%@", url.lastPathComponent];
const char *dirname = [url.lastPathComponent cStringUsingEncoding:NSUTF8StringEncoding];
_ig = init_ignore(parent.ig, dirname, strlen(dirname));
[self initScanDirBaton];
[self loadVcsIgnores];
return self;
}
- (void)initScanDirBaton {
_basePathCstr = (char *) cfstr_to_cstr_copy((__bridge CFStringRef) _baseUrl.path);
_pathStartCstr = (char *) cfstr_to_cstr_copy((__bridge CFStringRef) _pathStart);
_baton = malloc(sizeof(scandir_baton_t));
_baton->ig = _ig;
_baton->base_path = _basePathCstr;
_baton->base_path_len = strlen(_basePathCstr);
_baton->path_start = _pathStartCstr;
}
- (void)loadVcsIgnores {
const char *ignoreFile = NULL;
for (int i = 0; (ignore_pattern_files[i] != NULL); i++) {
ignoreFile = ignore_pattern_files[i];
char *dirFullPath = NULL;
ag_asprintf(
&dirFullPath,
"%s/%s",
[_url.path cStringUsingEncoding:NSUTF8StringEncoding],
ignoreFile
);
load_ignore_patterns(_ig, dirFullPath);
free(dirFullPath);
dirFullPath = NULL;
}
}
- (void)dealloc {
cleanup_ignore(_ig);
free(_baton);
free((void *) _basePathCstr);
free((void *) _pathStartCstr);
}
+ (instancetype)stubBatonWithGlobalGitignores {
static FileScanBaton *sharedStub = nil;
static dispatch_once_t singletonToken;
dispatch_once(&singletonToken, ^{
sharedStub = [[FileScanBaton alloc] initAsStub];
});
return sharedStub;
}
- (instancetype)initAsStub {
self = [super init];
if (self == nil) { return nil; }
_baseUrl = [NSURL fileURLWithPath:@"~"];
_url = _baseUrl;
_pathStart = @".";
_ig = init_ignore(NULL, "", 0);
[self initScanDirBaton];
load_global_gitignores(_ig);
return self;
}
static const char *cfstr_to_cstr_copy(CFStringRef cfstr) {
CFIndex out_len = 0;
CFRange whole_range = CFRangeMake(0, CFStringGetLength(cfstr));
CFIndex converted = CFStringGetBytes(
cfstr,
whole_range,
kCFStringEncodingUTF8,
0,
false,
NULL,
0,
&out_len
);
if (converted == 0 || out_len == 0) { return NULL; }
char *result = malloc((size_t) (out_len + 1));
converted = CFStringGetBytes(
cfstr,
whole_range,
kCFStringEncodingUTF8,
0,
false,
(UInt8 *) result,
out_len,
NULL
);
if (converted == 0) {
free(result);
return NULL;
}
result[out_len] = '\0';
return result;
}
// From the_silver_searcher/options.c
static void load_global_gitignores(ignores *ig) {
const char *home_dir = getenv("HOME");
FILE *gitconfig_file = NULL;
size_t buf_len = 0;
char *gitconfig_res = NULL;
gitconfig_file = popen("git config -z --path --get core.excludesfile 2>/dev/null", "r");
if (gitconfig_file != NULL) {
do {
gitconfig_res = ag_realloc(gitconfig_res, buf_len + 65);
buf_len += fread(gitconfig_res + buf_len, 1, 64, gitconfig_file);
} while (!feof(gitconfig_file) && buf_len > 0 && buf_len % 64 == 0);
gitconfig_res[buf_len] = '\0';
if (buf_len == 0) {
free(gitconfig_res);
const char *config_home = getenv("XDG_CONFIG_HOME");
if (config_home) {
ag_asprintf(&gitconfig_res, "%s/%s", config_home, "git/ignore");
} else {
ag_asprintf(&gitconfig_res, "%s/%s", home_dir, ".config/git/ignore");
}
}
log_debug("global core.excludesfile: %s", gitconfig_res);
load_ignore_patterns(ig, gitconfig_res);
free(gitconfig_res);
pclose(gitconfig_file);
}
}
@end

View File

@ -1,13 +0,0 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
#import <Foundation/Foundation.h>
@interface NSURL (Commons)
- (struct dirent)fakeDirent;
- (uint8_t)direntType;
@end

View File

@ -1,40 +0,0 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
#import "FoundationCommons.h"
#import <dirent.h>
@implementation NSURL (Commons)
- (struct dirent)fakeDirent {
const char *nameCstr = [self.lastPathComponent cStringUsingEncoding:NSUTF8StringEncoding];
struct dirent result = {
.d_type=self.direntType,
.d_namlen=(__uint16_t) strlen(nameCstr),
};
strcpy(result.d_name, nameCstr);
return result;
}
- (uint8_t)direntType {
NSString *value = nil;
if (![self getResourceValue:&value forKey:NSURLFileResourceTypeKey error:nil]) {
return DT_UNKNOWN;
}
if ([value isEqualToString:NSURLFileResourceTypeNamedPipe]) { return DT_FIFO; }
if ([value isEqualToString:NSURLFileResourceTypeCharacterSpecial]) { return DT_CHR; }
if ([value isEqualToString:NSURLFileResourceTypeDirectory]) { return DT_DIR; }
if ([value isEqualToString:NSURLFileResourceTypeBlockSpecial]) { return DT_BLK; }
if ([value isEqualToString:NSURLFileResourceTypeRegular]) { return DT_REG; }
if ([value isEqualToString:NSURLFileResourceTypeSymbolicLink]) { return DT_LNK; }
if ([value isEqualToString:NSURLFileResourceTypeSocket]) { return DT_SOCK; }
return DT_UNKNOWN;
}
@end

View File

@ -7,5 +7,10 @@ import Foundation
import os
extension URL {
var direntType: UInt8 { (self as NSURL).direntType() }
var direntType: Int16 {
if self.isRegularFile { return Int16(DT_REG)}
if self.hasDirectoryPath { return Int16(DT_DIR) }
return Int16(DT_UNKNOWN)
}
}

View File

@ -1,18 +0,0 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
#import <Foundation/Foundation.h>
@interface FuzzyMatcher : NSObject
+ (NSInteger)maxPatternLength;
+ (NSInteger)maxTextLength;
+ (NSInteger)minScore;
- (instancetype _Nonnull)initWithPattern:(NSString * _Nonnull)pattern;
- (NSInteger)score:(NSString * _Nonnull)text;
@end

View File

@ -1,33 +0,0 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
#import "FuzzyMatcher.h"
#import "fuzzy_match.hh"
@implementation FuzzyMatcher {
ccls::FuzzyMatcher *_matcher;
}
+ (NSInteger)maxPatternLength { return ccls::FuzzyMatcher::kMaxPat; }
+ (NSInteger)maxTextLength { return ccls::FuzzyMatcher::kMaxText; }
+ (NSInteger)minScore { return ccls::FuzzyMatcher::kMinScore; }
- (instancetype)initWithPattern:(NSString *)pattern {
self = [super init];
if (!self) { return nil; }
_matcher = new ccls::FuzzyMatcher([pattern cStringUsingEncoding:NSUTF8StringEncoding], 0);
return self;
}
- (NSInteger)score:(NSString *)text {
return _matcher->match([text cStringUsingEncoding:NSUTF8StringEncoding], false);
}
@end

View File

@ -1,52 +0,0 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
import Foundation
import os
class FuzzyMatcherPool {
let pattern: String
init(pattern: String, initialPoolSize: Int = 2) {
self.pattern = pattern
self.matchers = []
for _ in 0..<initialPoolSize { self.matchers.append(FuzzyMatcher(pattern: pattern)) }
}
func request() -> FuzzyMatcher {
self.lock.withLock {
if self.matchers.isEmpty {
let matcher = FuzzyMatcher(pattern: self.pattern)
return matcher
}
let matcher = self.matchers.popLast()! // We know that the array is not empty!
return matcher
}
}
func giveBack(_ matcher: FuzzyMatcher) {
self.lock.withLock { self.matchers.append(matcher) }
}
deinit {
self.log.debug(
"DEBUG FuzzyMatcherPool with pattern '\(self.pattern)' had \(self.matchers.count) matchers."
)
}
private var matchers: [FuzzyMatcher]
private let lock = NSLock()
private let log = OSLog(subsystem: Defs.loggerSubsystem, category: Defs.LoggerCategory.service)
}
private extension NSLocking {
func withLock<T>(_ body: () -> T) -> T {
self.lock()
defer { self.unlock() }
return body()
}
}

View File

@ -1,194 +0,0 @@
// Copyright 2017-2018 ccls Authors
// SPDX-License-Identifier: Apache-2.0
// Tae: From https://github.com/MaskRay/ccls/commit/61a1071634250b9e8f7f3c6be4e3966d9fb79e5b
// Added a cast to suppress warning
#include "fuzzy_match.hh"
#include <algorithm>
#include <ctype.h>
#include <stdio.h>
#include <vector>
namespace ccls {
namespace {
enum CharClass { Other, Lower, Upper };
enum CharRole { None, Tail, Head };
CharClass getCharClass(int c) {
if (islower(c))
return Lower;
if (isupper(c))
return Upper;
return Other;
}
void calculateRoles(std::string_view s, int roles[], int *class_set) {
if (s.empty()) {
*class_set = 0;
return;
}
CharClass pre = Other, cur = getCharClass(s[0]), suc;
*class_set = 1 << cur;
auto fn = [&]() {
if (cur == Other)
return None;
// U(U)L is Head while U(U)U is Tail
return pre == Other || (cur == Upper && (pre == Lower || suc == Lower))
? Head
: Tail;
};
for (size_t i = 0; i < s.size() - 1; i++) {
suc = getCharClass(s[i + 1]);
*class_set |= 1 << suc;
roles[i] = fn();
pre = cur;
cur = suc;
}
roles[s.size() - 1] = fn();
}
} // namespace
int FuzzyMatcher::missScore(int j, bool last) {
int s = -3;
if (last)
s -= 10;
if (text_role[j] == Head)
s -= 10;
return s;
}
int FuzzyMatcher::matchScore(int i, int j, bool last) {
int s = 0;
// Case matching.
if (pat[i] == text[j]) {
s++;
// pat contains uppercase letters or prefix matching.
if ((pat_set & 1 << Upper) || i == j)
s++;
}
if (pat_role[i] == Head) {
if (text_role[j] == Head)
s += 30;
else if (text_role[j] == Tail)
s -= 10;
}
// Matching a tail while previous char wasn't matched.
if (text_role[j] == Tail && i && !last)
s -= 30;
// First char of pat matches a tail.
if (i == 0 && text_role[j] == Tail)
s -= 40;
return s;
}
FuzzyMatcher::FuzzyMatcher(std::string_view pattern, int sensitivity) {
calculateRoles(pattern, pat_role, &pat_set);
if (sensitivity == 1)
sensitivity = pat_set & 1 << Upper ? 2 : 0;
case_sensitivity = sensitivity;
size_t n = 0;
for (size_t i = 0; i < pattern.size(); i++)
if (pattern[i] != ' ') {
pat += pattern[i];
low_pat[n] = (char)::tolower(pattern[i]);
pat_role[n] = pat_role[i];
n++;
}
}
int FuzzyMatcher::match(std::string_view text, bool strict) {
if (pat.empty() != text.empty())
return kMinScore;
int n = int(text.size());
if (n > kMaxText)
return kMinScore + 1;
this->text = text;
for (int i = 0; i < n; i++)
low_text[i] = (char)::tolower(text[i]);
calculateRoles(text, text_role, &text_set);
if (strict && n && !!pat_role[0] != !!text_role[0])
return kMinScore;
dp[0][0][0] = dp[0][0][1] = 0;
for (int j = 0; j < n; j++) {
dp[0][j + 1][0] = dp[0][j][0] + missScore(j, false);
dp[0][j + 1][1] = kMinScore * 2;
}
for (int i = 0; i < int(pat.size()); i++) {
int(*pre)[2] = dp[i & 1];
int(*cur)[2] = dp[(i + 1) & 1];
cur[i][0] = cur[i][1] = kMinScore;
for (int j = i; j < n; j++) {
cur[j + 1][0] = std::max(cur[j][0] + missScore(j, false),
cur[j][1] + missScore(j, true));
// For the first char of pattern, apply extra restriction to filter bad
// candidates (e.g. |int| in |PRINT|)
cur[j + 1][1] = (case_sensitivity ? pat[i] == text[j]
: low_pat[i] == low_text[j] &&
(i || text_role[j] != Tail ||
pat[i] == text[j]))
? std::max(pre[j][0] + matchScore(i, j, false),
pre[j][1] + matchScore(i, j, true))
: kMinScore * 2;
}
}
// Enumerate the end position of the match in str. Each removed trailing
// character has a penulty.
int ret = kMinScore;
for (int j = static_cast<int>(pat.size()); j <= n; j++)
ret = std::max(ret, dp[pat.size() & 1][j][1] - 2 * (n - j));
return ret;
}
} // namespace ccls
#if 0
TEST_SUITE("fuzzy_match") {
bool Ranks(std::string_view pat, std::vector<const char*> texts) {
FuzzyMatcher fuzzy(pat, 0);
std::vector<int> scores;
for (auto text : texts)
scores.push_back(fuzzy.Match(text));
bool ret = true;
for (size_t i = 0; i < texts.size() - 1; i++)
if (scores[i] < scores[i + 1]) {
ret = false;
break;
}
if (!ret) {
for (size_t i = 0; i < texts.size(); i++)
printf("%s %d ", texts[i], scores[i]);
puts("");
}
return ret;
}
TEST_CASE("test") {
FuzzyMatcher fuzzy("", 0);
CHECK(fuzzy.Match("") == 0);
CHECK(fuzzy.Match("aaa") < 0);
// case
CHECK(Ranks("monad", {"monad", "Monad", "mONAD"}));
// initials
CHECK(Ranks("ab", {"ab", "aoo_boo", "acb"}));
CHECK(Ranks("CC", {"CamelCase", "camelCase", "camelcase"}));
CHECK(Ranks("cC", {"camelCase", "CamelCase", "camelcase"}));
CHECK(Ranks("c c", {"camelCase", "camel case", "CamelCase", "camelcase",
"camel ace"}));
CHECK(Ranks("Da.Te",
{"Data.Text", "Data.Text.Lazy", "Data.Aeson.Encoding.text"}));
CHECK(Ranks("foo bar.h", {"foo/bar.h", "foobar.h"}));
// prefix
CHECK(Ranks("is", {"isIEEE", "inSuf"}));
// shorter
CHECK(Ranks("ma", {"map", "many", "maximum"}));
CHECK(Ranks("print", {"printf", "sprintf"}));
// score(PRINT) = kMinScore
CHECK(Ranks("ast", {"ast", "AST", "INT_FAST16_MAX"}));
// score(PRINT) > kMinScore
CHECK(Ranks("Int", {"int", "INT", "PRINT"}));
}
}
#endif

View File

@ -1,34 +0,0 @@
// Copyright 2017-2018 ccls Authors
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <limits.h>
#include <string>
#include <string_view>
namespace ccls {
class FuzzyMatcher {
public:
constexpr static int kMaxPat = 100;
constexpr static int kMaxText = PATH_MAX; // TAE: originally 200
// Negative but far from INT_MIN so that intermediate results are hard to
// overflow.
constexpr static int kMinScore = INT_MIN / 4;
FuzzyMatcher(std::string_view pattern, int case_sensitivity);
int match(std::string_view text, bool strict);
private:
int case_sensitivity;
std::string pat;
std::string_view text;
int pat_set, text_set;
char low_pat[kMaxPat], low_text[kMaxText];
int pat_role[kMaxPat], text_role[kMaxText];
int dp[2][kMaxText + 1][2];
int matchScore(int i, int j, bool last);
int missScore(int j, bool last);
};
} // namespace ccls

View File

@ -1,11 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="15702" systemVersion="19C57" minimumToolsVersion="Automatic" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="20086" systemVersion="21F79" minimumToolsVersion="Automatic" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="FileItem" representedClassName="FileItem" syncable="YES" codeGenerationType="class">
<attribute name="direntType" attributeType="Integer 16" usesScalarValueType="YES"/>
<attribute name="isHidden" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
<attribute name="isPackage" attributeType="Boolean" usesScalarValueType="YES"/>
<attribute name="needsScanChildren" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
<attribute name="pathStart" attributeType="String"/>
<attribute name="url" attributeType="URI"/>
<relationship name="children" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="FileItem" inverseName="parent" inverseEntity="FileItem"/>
<relationship name="parent" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="FileItem" inverseName="children" inverseEntity="FileItem"/>
@ -19,6 +18,6 @@
</fetchIndex>
</entity>
<elements>
<element name="FileItem" positionX="-63" positionY="-18" width="128" height="163"/>
<element name="FileItem" positionX="-63" positionY="-18" width="128" height="134"/>
</elements>
</model>

View File

@ -6,7 +6,9 @@
import Commons
import CoreData
import Foundation
import Ignore
import os
import Misc
class FuzzySearchService {
typealias ScoredUrlsCallback = ([ScoredUrl]) -> Void
@ -64,13 +66,13 @@ class FuzzySearchService {
self.stop = false
self.stopLock.unlock()
let matcherPool = FuzzyMatcherPool(pattern: pattern, initialPoolSize: 2)
let matcher = FzyMatcher(needle: pattern)
self.scanScoreSavedFiles(matcherPool: matcherPool, context: ctx, callback: callback)
self.scanScoreSavedFiles(matcher: matcher, context: ctx, callback: callback)
if self.shouldStop() { return }
self.scanScoreFilesNeedScanning(matcherPool: matcherPool, context: ctx, callback: callback)
self.scanScoreFilesNeedScanning(matcher: matcher, context: ctx, callback: callback)
}
self.log.info("Finished fuzzy search for \(pattern) in \(self.root)")
@ -78,7 +80,7 @@ class FuzzySearchService {
}
private func scanScoreSavedFiles(
matcherPool: FuzzyMatcherPool,
matcher: FzyMatcher,
context: NSManagedObjectContext,
callback: ScoredUrlsCallback
) {
@ -91,7 +93,7 @@ class FuzzySearchService {
self.log.error("Could not get count of Files")
return
}
self.log.info("Scoring \(count) Files for pattern \(matcherPool.pattern)")
self.log.info("Scoring \(count) Files for pattern \(matcher.needle)")
let urlSorter = NSSortDescriptor(key: "url", ascending: true)
let fetchReq = FileItem.fetchRequest()
@ -107,7 +109,7 @@ class FuzzySearchService {
fetchReq.fetchOffset = start
do {
self.scoreFiles(
matcherPool: matcherPool,
matcher: matcher,
files: try context.fetch(fetchReq),
callback: callback
)
@ -120,7 +122,7 @@ class FuzzySearchService {
}
private func scanScoreFilesNeedScanning(
matcherPool: FuzzyMatcherPool,
matcher: FzyMatcher,
context: NSManagedObjectContext,
callback: ([ScoredUrl]) -> Void
) {
@ -131,7 +133,7 @@ class FuzzySearchService {
// foldersToScan after first folderToScan.
foldersToScan.forEach { folder in
self.scanScore(
matcherPool: matcherPool,
matcher: matcher,
folderId: folder.objectID,
context: context,
callback: callback
@ -143,7 +145,7 @@ class FuzzySearchService {
}
private func scanScore(
matcherPool: FuzzyMatcherPool,
matcher: FzyMatcher,
folderId: NSManagedObjectID,
context: NSManagedObjectContext,
callback: ([ScoredUrl]) -> Void
@ -156,9 +158,8 @@ class FuzzySearchService {
return
}
let (initialBaton, initialBatons) = self.baton(for: folder.url!)
let initialBaton = self.ignoreService.ignoreCollection(forUrl: folder.url!)
let testIgnores = self.usesVcsIgnores
var batons = initialBatons
var stack = [(initialBaton, folder)]
while let iterElement = stack.popLast() {
if self.shouldStop({ self.saveAndReset(context: context) }) { return }
@ -172,16 +173,16 @@ class FuzzySearchService {
let childUrls = FileUtils
.directDescendants(of: urlToScan)
.filter {
let keep = testIgnores ? baton.test($0) : true
if !keep { self.log.debug("Ignoring \($0.path)") }
return keep
guard testIgnores, let ignore = baton else { return true }
let isExcluded = ignore.excludes($0)
if isExcluded { self.log.debug("Ignoring \($0.path)") }
return !isExcluded
}
let childFiles = childUrls
.filter { !$0.isPackage }
.map { url -> FileItem in
self.file(fromUrl: url, pathStart: baton.pathStart, in: context)
}
.map { url -> FileItem in self.file(fromUrl: url, in: context) }
saveCounter += childFiles.count
counter += childFiles.count
@ -189,9 +190,8 @@ class FuzzySearchService {
folder.needsScanChildren = false
let childFolders = childFiles.filter { $0.direntType == DT_DIR }
let childBatons = childFolders.map { FileScanBaton(parent: baton, url: $0.url!) }
let childBatons = childFolders.map { self.ignoreService.ignoreCollection(forUrl: $0.url!) }
batons.append(contentsOf: childBatons)
stack.append(contentsOf: zip(childBatons, childFolders))
if saveCounter > coreDataBatchSize {
@ -199,7 +199,7 @@ class FuzzySearchService {
"Flushing and scoring \(saveCounter) Files, stack has \(stack.count) Files"
)
self.scoreAllRegisteredFiles(
matcherPool: matcherPool,
matcher: matcher,
context: context,
callback: callback
)
@ -220,7 +220,7 @@ class FuzzySearchService {
}
self.log.debug("Flushing and scoring last \(saveCounter) Files")
self.scoreAllRegisteredFiles(matcherPool: matcherPool, context: context, callback: callback)
self.scoreAllRegisteredFiles(matcher: matcher, context: context, callback: callback)
self.saveAndReset(context: context)
self.log.debug("Stored \(counter) Files")
@ -248,7 +248,7 @@ class FuzzySearchService {
}
private func scoreAllRegisteredFiles(
matcherPool: FuzzyMatcherPool,
matcher: FzyMatcher,
context: NSManagedObjectContext,
callback: ([ScoredUrl]) -> Void
) {
@ -257,32 +257,33 @@ class FuzzySearchService {
.filter { $0.direntType != DT_DIR }
self.log.debug("Scoring \(files.count) Files")
self.scoreFiles(matcherPool: matcherPool, files: files, callback: callback)
self.scoreFiles(matcher: matcher, files: files, callback: callback)
}
private func scoreFiles(
matcherPool: FuzzyMatcherPool,
matcher: FzyMatcher,
files: [FileItem],
callback: ScoredUrlsCallback
) {
let matchFullPath = matcherPool.pattern.contains("/")
let matchFullPath = matcher.needle.contains("/")
let count = files.count
let chunkCount = Int(ceil(Double(count) / Double(fuzzyMatchChunkSize)))
DispatchQueue.concurrentPerform(iterations: chunkCount) { chunkIndex in
let matcher = matcherPool.request()
defer { matcherPool.giveBack(matcher) }
let start = Swift.min(chunkIndex * fuzzyMatchChunkSize, count)
let end = Swift.min(start + fuzzyMatchChunkSize, count)
if self.shouldStop() { return }
let scoreThreshold = FuzzyMatcher.minScore() + 1
let scoreThreshold = 1.0
callback(files[start..<end].compactMap { file in
let url = file.url!
let score = matcher.score(matchFullPath ? url.path : url.lastPathComponent)
if score <= scoreThreshold { return nil }
let haystack = matchFullPath ? url.path : url.lastPathComponent
guard matcher.hasMatch(haystack) else { return nil }
let score = matcher.score(haystack)
if score < scoreThreshold { return nil }
return ScoredUrl(url: url, score: score)
})
@ -298,6 +299,8 @@ class FuzzySearchService {
self.root = root
self.writeContext = self.coreDataStack.newBackgroundContext()
self.ignoreService = IgnoreService(count: 500, root: root)
self.queue.sync { self.ensureRootFileInStore() }
try self.fileMonitor.monitor(url: root) { [weak self] url in self?.handleChange(in: url) }
}
@ -310,7 +313,7 @@ class FuzzySearchService {
do {
let files = try ctx.fetch(req)
guard files.isEmpty else { return }
_ = self.file(fromUrl: self.root, pathStart: ".", in: ctx)
_ = self.file(fromUrl: self.root, in: ctx)
try ctx.save()
} catch {
self.log.error("Could not ensure root File in Core Data: \(error)")
@ -374,45 +377,13 @@ class FuzzySearchService {
}
}
private func baton(for url: URL) -> (FileScanBaton, [FileScanBaton]) {
assert(self.root.isAncestor(of: url) || url == self.root)
if url == self.root {
let rootBaton = FileScanBaton(baseUrl: self.root)
return (rootBaton, [rootBaton])
}
let rootBaton = FileScanBaton(baseUrl: self.root)
var batons = [rootBaton]
var pathComps = url.pathComponents.suffix(from: self.root.pathComponents.count)
var lastBaton = rootBaton
var lastUrl = self.root
while let pathComp = pathComps.popFirst() {
let childUrl = lastUrl.appendingPathComponent(pathComp)
let childBaton = FileScanBaton(parent: lastBaton, url: childUrl)
batons.append(childBaton)
lastBaton = childBaton
lastUrl = childUrl
}
return (lastBaton, batons)
}
private func file(
fromUrl url: URL,
pathStart: String,
in context: NSManagedObjectContext
) -> FileItem {
private func file(fromUrl url: URL, in context: NSManagedObjectContext) -> FileItem {
let file = FileItem(context: context)
file.url = url
file.direntType = Int16(url.direntType)
file.direntType = url.direntType
file.isHidden = url.isHidden
file.isPackage = url.isPackage
file.pathStart = pathStart
if url.isDir { file.needsScanChildren = true }
if url.hasDirectoryPath { file.needsScanChildren = true }
return file
}
@ -446,6 +417,7 @@ class FuzzySearchService {
private let fileMonitor = FileMonitor()
private let writeContext: NSManagedObjectContext
private let ignoreService: IgnoreService
private let log = OSLog(subsystem: Defs.loggerSubsystem, category: Defs.LoggerCategory.service)
}

View File

@ -158,9 +158,7 @@ class GeneralPref: PrefPane, UiComponent, NSTextFieldDelegate {
self.infoTextField(markdown: #"""
When checked, the ignore files of VCSs, e.g. `gitignore`, will we used to ignore files.\
This checkbox will set the initial value for each VimR window.\
You can change this setting for each VimR window in the Open Quickly window.\
The behavior should be almost identical to that of
[The Silver Searcher](https://github.com/ggreer/the_silver_searcher).
You can change this setting for each VimR window in the Open Quickly window.
"""#)
let cliToolTitle = self.titleTextField(title: "CLI Tool:")

View File

@ -0,0 +1,82 @@
/// Tae Won Ha - http://taewon.de - @hataewon
/// See LICENSE
import Foundation
import Ignore
import OrderedCollections
class IgnoreService {
var root: URL {
didSet {
self.rootIgnore = Ignore(
base: self.root,
parent: Ignore.globalGitignoreCollection(base: self.root)
)
}
}
init(count: Int, root: URL) {
self.root = root
self.count = count
self.queue = DispatchQueue(
label: "\(String(reflecting: IgnoreService.self))-\(UUID().uuidString)",
qos: .default,
target: .global(qos: DispatchQoS.default.qosClass)
)
self.storage = OrderedDictionary(minimumCapacity: count)
self.rootIgnore = Ignore(
base: root,
parent: Ignore.globalGitignoreCollection(base: root)
)
}
func ignoreCollection(forUrl url: URL) -> Ignore? {
self.queue.sync {
if self.root == url { return self.rootIgnore }
guard self.root.isAncestor(of: url) else { return nil }
if url == self.root { return self.rootIgnore }
if let ignore = self.storage[url] { return ignore }
if let parentIgnore = self.storage[url.parent] {
let ignore = Ignore(base: url, parent: parentIgnore)
self.storage[url] = ignore
return ignore
}
// Since we descend the directory structure step by step, the ignore of the parent should
// already be present. Most probably we won't land here...
let rootPathComp = self.root.pathComponents
let pathComp = url.pathComponents.dropLast()
let lineage = pathComp.suffix(from: rootPathComp.count)
var ancestorUrl = self.root
var ancestorIc = self.rootIgnore
for ancestorComponent in lineage {
ancestorUrl = ancestorUrl.appendingPathComponent(ancestorComponent, isDirectory: true)
if self.storage[ancestorUrl] == nil {
guard let ignore = Ignore(base: ancestorUrl, parent: ancestorIc) else {
return nil
}
self.set(ignoreCollection: ignore, forUrl: url)
ancestorIc = ignore
}
}
return ancestorIc
}
}
private func set(ignoreCollection: Ignore, forUrl url: URL) {
if self.storage.count == self.count { self.storage.removeFirst() }
self.storage[url] = ignoreCollection
}
private var rootIgnore: Ignore?
private let count: Int
private var storage: OrderedDictionary<URL, Ignore>
private let queue: DispatchQueue
}

View File

@ -1224,7 +1224,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>SNAPSHOT-20220419.180005</string>
<string>SNAPSHOT-20220616.153112</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
@ -1241,7 +1241,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>20220419.180005</string>
<string>20220616.153112</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.productivity</string>
<key>LSMinimumSystemVersion</key>
@ -1272,7 +1272,7 @@
</dict>
</dict>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2016 Tae Won Ha. All rights reserved.</string>
<string>Copyright © 2022 Tae Won Ha. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>

View File

@ -9,15 +9,12 @@
@interface ScoredUrl : NSObject
@property (readonly, nonnull) NSURL *url;
@property (readonly) NSInteger score;
@property (readonly) double score;
- (instancetype _Nonnull)initWithUrl:(NSURL * _Nonnull)url score:(double)score;
- (NSString * _Nonnull)description;
- (BOOL)isEqual:(id _Nullable)other;
- (BOOL)isEqualToUrl:(ScoredUrl * _Nullable)url;
- (NSUInteger)hash;
- (instancetype _Nonnull)initWithUrl:(NSURL * _Nonnull)url score:(NSInteger)score;
- (NSString * _Nonnull)description;
+ (instancetype _Nonnull)urlWithUrl:(NSURL * _Nonnull)url score:(NSInteger)score;
@end

View File

@ -31,8 +31,8 @@
}
- (NSUInteger)hash {
NSUInteger hash = [self.url hash];
hash = hash * 31u + self.score;
NSUInteger hash = self.url.hash;
hash = hash * 31u + @(self.score).hash;
return hash;
}
@ -40,12 +40,12 @@
NSMutableString *description
= [NSMutableString stringWithFormat:@"<%@: ", NSStringFromClass([self class])];
[description appendFormat:@"self.url=%@", self.url.path];
[description appendFormat:@", self.score=%li", self.score];
[description appendFormat:@", self.score=%f", self.score];
[description appendString:@">"];
return description;
}
- (instancetype)initWithUrl:(NSURL *)url score:(NSInteger)score {
- (instancetype)initWithUrl:(NSURL *)url score:(double)score {
self = [super init];
if (!self) { return nil; }
@ -55,8 +55,4 @@
return self;
}
+ (instancetype)urlWithUrl:(NSURL *)url score:(NSInteger)score {
return [[self alloc] initWithUrl:url score:score];
}
@end

View File

@ -15,10 +15,10 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>SNAPSHOT-20220419.180005</string>
<string>SNAPSHOT-20220616.153112</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>20220419.180005</string>
<string>20220616.153112</string>
</dict>
</plist>

View File

@ -1,4 +1,4 @@
// swift-tools-version:5.3
// swift-tools-version:5.6
import PackageDescription
@ -9,22 +9,18 @@ let package = Package(
.library(name: "Workspace", targets: ["Workspace"]),
],
dependencies: [
.package(
name: "PureLayout",
url: "https://github.com/PureLayout/PureLayout",
.upToNextMinor(from: "3.1.9")
),
.package(
name: "MaterialIcons",
url: "https://github.com/qvacua/material-icons",
.upToNextMinor(from: "0.1.0")
),
.package(url: "https://github.com/PureLayout/PureLayout", from: "3.1.9"),
.package(url: "https://github.com/qvacua/material-icons", from: "0.1.0"),
.package(path: "../Commons"),
],
targets: [
.target(
name: "Workspace",
dependencies: ["PureLayout", "MaterialIcons", "Commons"]
dependencies: [
"PureLayout",
.product(name: "MaterialIcons", package: "material-icons"),
"Commons",
]
),
.testTarget(
name: "WorkspaceTests",

View File

@ -6,22 +6,27 @@
<description>Most recent changes with links to updates for VimR.</description>
<language>en</language>
<item>
<title>SNAPSHOT-20220419.180005</title>
<title>SNAPSHOT-20220616.153112</title>
<link>https://twitter.com/vimrefined</link>
<sparkle:version>20220419.180005</sparkle:version>
<sparkle:shortVersionString>SNAPSHOT-20220419.180005</sparkle:shortVersionString>
<sparkle:version>20220616.153112</sparkle:version>
<sparkle:shortVersionString>SNAPSHOT-20220616.153112</sparkle:shortVersionString>
<description><![CDATA[
<ul>
<li>Improved tracpad scrolling sensitivity (removed the option for customizing the sensitivity). Thanks @tsung-ju for the PR!</li>
<p>Since last snapshot:</p>
<ul>
<li>Refactor open quickly:</li>
<li>Use <a href="https://github.com/jhawthorn/fzy">fzy</a> instead of <a href="https://github.com/MaskRay/ccls">ccls</a></li>
<li>Replace <a href="https://github.com/ggreer/the_silver_searcher">The Silver Searcher</a>'s ignore mechanism with own implementation in Swift using <a href="https://github.com/davvid/wildmatch">wildmatch</a></li>
<li>Dependencies updates</li>
<li>qvacua/misc.swift@0.0.1</li>
</ul>
]]></description>
<releaseNotesLink>
https://github.com/qvacua/vimr/releases/tag/snapshot/20220419.180005
https://github.com/qvacua/vimr/releases/tag/snapshot/20220616.153112
</releaseNotesLink>
<pubDate>2022-04-19T18:07:05.128691</pubDate>
<pubDate>2022-06-16T15:50:06.459400</pubDate>
<minimumSystemVersion>10.13.0</minimumSystemVersion>
<enclosure url="https://github.com/qvacua/vimr/releases/download/snapshot/20220419.180005/VimR-SNAPSHOT-20220419.180005.tar.bz2"
sparkle:edSignature="MBXpZfvD/qaXWkqpFM8eeeTxXOnEcjiBGzRRJxpj88DepCbES/diPnNECk832A5TS0clt2j/iyzDq7nxFzzCCw==" length="20981009"
<enclosure url="https://github.com/qvacua/vimr/releases/download/snapshot/20220616.153112/VimR-SNAPSHOT-20220616.153112.tar.bz2"
sparkle:edSignature="Q+Hh7w0nDchwWlTMsqxJqgHh1wsw+1276pNndYOIPjpbtg/35Ui2V0UT5cGTiA5v+Lx9z5+OxlAALuaMuu41BA==" length="21554338"
type="application/octet-stream"/>
</item>
</channel>

View File

@ -12,38 +12,5 @@
* Install the requirements
```bash
pip install -r requirements.txt
python setup.py develop
```
## How to build third party dependencies
* Run `build.py` with, for example, the following arguments
```
$ python build.py --arm64-deployment-target=11.00 --x86_64-deployment-target=10.13 \
--xz-version 5.2.4 --pcre-version 8.43 --ag-version 2.2.0
```
### Built artifacts
The resulting artifacts are structured as follows
```
./third_party
vimr-deps
lib
liba.a
libb.a
...
include
a.h
b.h
...
liba
include
a.h
...
libb
include
b.h
...
```

View File

@ -1,29 +0,0 @@
#!/bin/bash
set -Eeuo pipefail
main () {
pushd "$(dirname "${BASH_SOURCE[0]}")/.." > /dev/null
local x86_64_deployment_target
x86_64_deployment_target="$(jq -r .deploymentTargets.x86_64 ./resources/buildInfo.json)"
readonly x86_64_deployment_target
local arm64_deployment_target
arm64_deployment_target="$(jq -r .deploymentTargets.arm64 ./resources/buildInfo.json)"
readonly arm64_deployment_target
local -r pcre_version="8.45"
local -r xz_version="5.3.2alpha"
local -r ag_version="2.2.0"
pushd ./bin >/dev/null
python third_party/build.py \
--arm64-deployment-target="${arm64_deployment_target}" \
--x86_64-deployment-target="${x86_64_deployment_target}" \
--xz-version "${xz_version}" \
--pcre-version "${pcre_version}" \
--ag-version "${ag_version}"
popd >/dev/null
popd >/dev/null
}
main

View File

@ -56,7 +56,7 @@ check_gh_release_present() {
build_release() {
echo "### Building release"
code_sign=true use_carthage_cache=false download_deps=true ./bin/build_vimr.sh
code_sign=true use_carthage_cache=false ./bin/build_vimr.sh
vimr_app_path="${build_folder_path}/VimR.app" ./bin/notarize_vimr.sh

View File

@ -3,17 +3,11 @@ set -Eeuo pipefail
readonly code_sign=${code_sign:?"true or false"}
readonly use_carthage_cache=${use_carthage_cache:?"true or false"}
readonly download_deps=${download_deps:?"true or false: when true, vimr-deps is downloaded"}
main () {
pushd "$(dirname "${BASH_SOURCE[0]}")/.." >/dev/null
echo "### Building VimR target"
if [[ "${download_deps}" == true ]]; then
rm -rf ./VimR/.deps
./bin/download_vimr_deps.sh
fi
local -r build_path="./build"
# Carthage often crashes => do it at the beginning.

View File

@ -2,7 +2,6 @@
set -Eeuo pipefail
readonly clean=${clean:?"true or false: when true, xcodebuild clean will be performed"}
readonly download_deps=${download_deps:-false}
main() {
if [[ "${clean}" == true ]]; then
@ -12,11 +11,6 @@ main() {
fi
pushd "$(dirname "${BASH_SOURCE[0]}")/.." > /dev/null
if [[ "${download_deps}" == true ]]; then
rm -rf ./VimR/.deps
./bin/download_vimr_deps.sh
fi
xcodebuild \
-workspace VimR.xcworkspace \
-derivedDataPath ./build \

View File

@ -1,37 +0,0 @@
#!/bin/bash
set -Eeuo pipefail
readonly target_dir_path="VimR/.deps"
readonly file_name="vimr-deps"
readonly compressed_file_name="${file_name}.tar.bz2"
download_vimr_deps() {
echo "### Downloading ${file_name}"
local version
version="$(jq -r .dependencies.vimrDeps ./resources/buildInfo.json)"
readonly version
echo "#### Downloading ${version}"
rm -rf "${target_dir_path}"
mkdir -p ${target_dir_path}
curl -o "${target_dir_path}/vimr-deps.tar.bz2" -L "https://github.com/qvacua/vimr/releases/download/${version}/${compressed_file_name}"
pushd ${target_dir_path} >/dev/null
tar xf "${compressed_file_name}"
rm ${compressed_file_name}
mv "${file_name}"/* .
rm -r "${file_name}"
popd >/dev/null
echo "### Downloaded ${file_name}"
}
main() {
pushd "$(dirname "${BASH_SOURCE[0]}")/.." > /dev/null
download_vimr_deps
popd >/dev/null
}
main

View File

@ -60,14 +60,15 @@ declare -r -x bundle_version=${bundle_version}
declare -r -x marketing_version=${marketing_version}
declare -r -x tag=${tag}
declare -r -x github_release_name=${github_release_name}
declare -r -x release_notes=\$(cat <<-ENDRN
replace-me
ENDRN
)
declare -r -x release_notes=\$(cat release-notes.temp.md)
# Add release notes to release-notes.temp.md and issue
# create_gh_release=true upload=true update_appcast=true release_spec_file=${bundle_version}-${version_marker}.sh ./bin/build_release.sh
END
)
readonly output
echo "Release notes" > release-notes.temp.md
echo "${output}" > "${bundle_version}-${version_marker}.sh"
echo "### Tag, commit and push with ${tag}"

View File

@ -1,10 +0,0 @@
import setuptools
setuptools.setup(
name="com.qvacua.VimR.bin",
version="0.0.0",
author="Tae Won Ha",
description="Scripts for building VimR",
packages=setuptools.find_packages(),
python_requires=">=3.9",
)

View File

@ -1,9 +0,0 @@
#!/bin/bash
set -e
set -o pipefail
if [ "$#" -ne 2 ]; then
echo "Usage: $0 update_archive private_key"
exit 1
fi
openssl=/usr/bin/openssl
$openssl dgst -sha1 -binary < "$1" | $openssl dgst -dss1 -sign "$2" | $openssl enc -base64

View File

View File

@ -1,130 +0,0 @@
import argparse
import pathlib
import shutil
from third_party.config import Config
from third_party.deps import ag, pcre, xz
from third_party.deps.ag import AgBuilder
from third_party.builder import Builder
DEPS_FILE_NAME = ".deps"
PACKAGE_NAME = "vimr-deps"
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument(
"--xz-version",
action="store",
dest="xz_version",
type=str,
required=True,
)
parser.add_argument(
"--pcre-version",
action="store",
dest="pcre_version",
type=str,
required=True,
)
parser.add_argument(
"--ag-version",
action="store",
dest="ag_version",
type=str,
required=True,
)
parser.add_argument(
"--arm64-deployment-target",
action="store",
dest="arm64_deployment_target",
type=str,
required=True,
)
parser.add_argument(
"--x86_64-deployment-target",
action="store",
dest="x86_64_deployment_target",
type=str,
required=False,
)
return parser.parse_args()
if __name__ == "__main__":
args = parse_args()
arm64_deployment_target = args.arm64_deployment_target
x86_64_deployment_target = args.x86_64_deployment_target
cwd = pathlib.Path(__file__).parent.resolve().joinpath("build")
shutil.rmtree(cwd, ignore_errors=True)
cwd.mkdir(parents=True, exist_ok=True)
install_path = cwd.parent.joinpath(PACKAGE_NAME)
shutil.rmtree(install_path, ignore_errors=True)
install_path_lib = install_path.joinpath("lib")
install_path_include = install_path.joinpath("include")
xz_config = Config(
version=args.xz_version,
arm64_deployment_target=arm64_deployment_target,
x86_64_deployment_target=x86_64_deployment_target,
default_cflags="-g -O2",
target_install_path_parent=cwd.joinpath("libxz"),
install_path_lib=install_path_lib,
install_path_include=install_path_include,
working_directory=cwd.joinpath(DEPS_FILE_NAME),
)
pcre_config = Config(
version=args.pcre_version,
arm64_deployment_target=arm64_deployment_target,
x86_64_deployment_target=x86_64_deployment_target,
default_cflags="-D_THREAD_SAFE -pthread -g -O2",
target_install_path_parent=cwd.joinpath("libpcre"),
install_path_lib=install_path_lib,
install_path_include=install_path_include,
working_directory=cwd.joinpath(DEPS_FILE_NAME),
)
ag_config = Config(
version=args.ag_version,
arm64_deployment_target=arm64_deployment_target,
x86_64_deployment_target=x86_64_deployment_target,
default_cflags="-g -O2 -D_THREAD_SAFE -pthread",
target_install_path_parent=cwd.joinpath("libag"),
install_path_lib=install_path_lib,
install_path_include=install_path_include,
working_directory=cwd.joinpath(DEPS_FILE_NAME),
)
builders = {
"xz": Builder(
xz_config,
download_command=xz.download_command,
extract_command=xz.extract_command,
make_command=xz.make_command,
build_universal_and_install_command=xz.build_universal_and_install_command,
),
"pcre": Builder(
pcre_config,
download_command=pcre.download_command,
make_command=pcre.make_command,
extract_command=pcre.extract_command,
build_universal_and_install_command=pcre.build_universal_and_install_command,
),
"ag": AgBuilder(
ag_config,
download_command=ag.download_command,
make_command=ag.make_command,
deps=[xz_config, pcre_config],
extract_command=ag.extract_command,
build_universal_and_install_command=ag.build_universal_and_install_command,
),
}
builders["xz"].build()
builders["pcre"].build()
builders["ag"].build()

View File

@ -1,76 +0,0 @@
from dataclasses import dataclass
from string import Template
from third_party.config import Config, Target
from third_party.utils.shell import shell
@dataclass(frozen=True)
class Builder:
config: Config
download_command: Template
extract_command: Template
make_command: Template
build_universal_and_install_command: Template
def download(self):
cmd = self.download_command.substitute(dict(version=self.config.version))
print(cmd)
shell(cmd, cwd=self.config.working_directory)
def extract(self, target: Target):
cmd = self.extract_command.substitute(
dict(
target=target.value,
version=self.config.version,
)
)
print(cmd)
shell(cmd, cwd=self.config.working_directory)
def make(self, target: Target):
cmd = self.make_command.substitute(
dict(
target=target.value,
cflags=self.config.target_specific_full_cflags(target),
deployment_target=self.config.target_specific_deployment_target(target),
install_path=self.config.target_specific_install_path(target),
host=self.config.target_specific_host(target),
)
)
print(cmd)
shell(cmd, cwd=self.config.working_directory)
def build_universal_and_install(self):
cmd = self.build_universal_and_install_command.substitute(
dict(
install_lib_path=self.config.install_path_lib,
install_include_path=self.config.install_path_include,
arm64_lib_path=self.config.target_specific_install_path(Target.arm64).joinpath(
"lib"
),
arm64_include_path=self.config.target_specific_install_path(Target.arm64).joinpath(
"include"
),
x86_64_lib_path=self.config.target_specific_install_path(Target.x86_64).joinpath(
"lib"
),
)
)
print(cmd)
shell(cmd, cwd=self.config.working_directory)
def build(self):
self.config.clean_install_paths()
self.config.ensure_paths_exist()
self.download()
self.extract(Target.arm64)
self.make(Target.arm64)
self.extract(Target.x86_64)
self.make(Target.x86_64)
self.build_universal_and_install()

View File

@ -1,89 +0,0 @@
import shutil
from dataclasses import dataclass
from enum import Enum
from pathlib import Path
class Target(Enum):
arm64 = "arm64"
x86_64 = "x86_64"
@dataclass(frozen=True)
class Config:
"""The working_directory should be set for the particular library, e.g. ./.deps/xz"""
version: str
arm64_deployment_target: str
x86_64_deployment_target: str
default_cflags: str
target_install_path_parent: Path
install_path_include: Path
install_path_lib: Path
working_directory: Path
def target_specific_host(self, target: Target) -> str:
if target is Target.arm64:
return "arm-apple-macos"
elif target is Target.x86_64:
return "x86_64-apple-macos"
else:
raise ValueError
def target_specific_deployment_target(self, target: Target) -> str:
if target is Target.arm64:
return self.arm64_deployment_target
elif target is Target.x86_64:
return self.x86_64_deployment_target
else:
raise ValueError
def target_specific_full_cflags(self, target: Target) -> str:
if target is Target.arm64:
return self.arm64_full_cflags
elif target is Target.x86_64:
return self.x86_64_full_cflags
else:
raise ValueError
def target_specific_install_path(self, target: Target) -> Path:
if target is Target.arm64:
return self.arm64_install_path
elif target is Target.x86_64:
return self.x86_64_install_path
else:
raise ValueError
@property
def arm64_full_cflags(self) -> str:
return f"{self.default_cflags} --target=arm64-apple-macos{self.arm64_deployment_target}"
@property
def x86_64_full_cflags(self) -> str:
return f"{self.default_cflags} --target=x86_64-apple-macos{self.x86_64_deployment_target}"
@property
def arm64_install_path(self) -> Path:
return self.target_install_path_parent.joinpath("arm64")
@property
def x86_64_install_path(self) -> Path:
return self.target_install_path_parent.joinpath("x86_64")
def clean_install_paths(self):
shutil.rmtree(self.arm64_install_path, ignore_errors=True)
shutil.rmtree(self.x86_64_install_path, ignore_errors=True)
shutil.rmtree(self.target_install_path_parent, ignore_errors=True)
def ensure_paths_exist(self):
self.target_install_path_parent.mkdir(parents=True, exist_ok=True)
self.install_path_lib.mkdir(parents=True, exist_ok=True)
self.install_path_include.mkdir(parents=True, exist_ok=True)
self.arm64_install_path.mkdir(parents=True, exist_ok=True)
self.x86_64_install_path.mkdir(parents=True, exist_ok=True)
self.working_directory.mkdir(parents=True, exist_ok=True)

View File

View File

@ -1,74 +0,0 @@
from dataclasses import dataclass
from string import Template
from third_party.builder import Builder
from third_party.config import Config, Target
from third_party.utils.shell import shell
# language=bash
download_command = Template(
"""
curl -L -s -o ag.tar.gz https://github.com/ggreer/the_silver_searcher/archive/${version}.tar.gz
"""
)
# language=bash
extract_command = Template(
"""
rm -rf "ag-${target}"
tar xf ag.tar.gz
mv "the_silver_searcher-${version}" "ag-${target}"
"""
)
# language=bash
make_command = Template(
"""
pushd ag-${target} >/dev/null
./autogen.sh
./configure
CFLAGS="${cflags} ${include_flags}" \
LDFLAGS="${ldflags}" \
MACOSX_DEPLOYMENT_TARGET="${deployment_target}"
pushd src > /dev/null
cc ${cflags} ${include_flags} -c ignore.c log.c options.c print.c scandir.c search.c lang.c util.c decompress.c zfile.c
ar -crs libag.a ignore.o log.o options.o print.o scandir.o search.o lang.o util.o decompress.o zfile.o
mkdir -p "${install_path}/lib"
mv libag.a "${install_path}/lib"
mkdir -p "${install_path}/include"
cp *.h "${install_path}/include"
popd >/dev/null
popd >/dev/null
"""
)
# language=bash
build_universal_and_install_command = Template(
"""
lipo -create -output "${install_lib_path}/libag.a" "${arm64_lib_path}/libag.a" "${x86_64_lib_path}/libag.a"
cp -r "${arm64_include_path}"/* "${install_include_path}"
"""
)
@dataclass(frozen=True)
class AgBuilder(Builder):
deps: [Config]
def make(self, target: Target):
include_flags = f"-I{self.config.install_path_include}"
ldflags = f"-L{self.config.install_path_lib}"
cmd = self.make_command.substitute(
dict(
target=target.value,
cflags=self.config.target_specific_full_cflags(target),
ldflags=ldflags,
include_flags=include_flags,
deployment_target=self.config.target_specific_deployment_target(target),
install_path=self.config.target_specific_install_path(target),
)
)
print(cmd)
shell(cmd, cwd=self.config.working_directory)

View File

@ -1,52 +0,0 @@
from string import Template
# "https://ftp.pcre.org/pub/pcre/pcre-${version}.tar.bz2" seems to be down as of 2021-11-04.
# language=bash
download_command = Template(
"""
curl -L -s -o pcre.tar.bz2 "https://www.mirrorservice.org/sites/ftp.exim.org/pub/pcre/pcre-${version}.tar.bz2"
"""
)
# language=bash
extract_command = Template(
"""
rm -rf "pcre-${target}"
tar xf pcre.tar.bz2
mv "pcre-${version}" "pcre-${target}"
"""
)
# language=bash
make_command = Template(
"""
pushd pcre-${target} >/dev/null
./configure \
CFLAGS="${cflags}" \
CXXFLAGS="${cflags}" \
MACOSX_DEPLOYMENT_TARGET="${deployment_target}" \
--disable-dependency-tracking \
--enable-utf8 \
--enable-pcre8 \
--enable-pcre16 \
--enable-pcre32 \
--enable-unicode-properties \
--enable-pcregrep-libz \
--enable-pcregrep-libbz2 \
--enable-jit=no \
--disable-shared \
--host="${host}" \
--prefix="${install_path}"
make MACOSX_DEPLOYMENT_TARGET="${deployment_target}" install
popd >/dev/null
"""
)
# language=bash
build_universal_and_install_command = Template(
"""
lipo -create -output "${install_lib_path}/libpcre.a" "${arm64_lib_path}/libpcre.a" "${x86_64_lib_path}/libpcre.a"
cp -r "${arm64_include_path}"/* "${install_include_path}"
"""
)

View File

@ -1,50 +0,0 @@
from string import Template
# language=bash
download_command = Template(
"""
curl -L -s -o xz.tar.gz "https://tukaani.org/xz/xz-${version}.tar.gz"
"""
)
# language=bash
extract_command = Template(
"""
rm -rf "xz-${target}"
tar xf xz.tar.gz
mv "xz-${version}" "xz-${target}"
"""
)
# language=bash
make_command = Template(
"""
pushd ./xz-${target} >/dev/null
./configure \
CFLAGS="${cflags}" \
MACOSX_DEPLOYMENT_TARGET="${deployment_target}" \
--disable-debug \
--disable-dependency-tracking \
--disable-silent-rules \
--disable-shared \
--disable-xz \
--disable-xzdec \
--disable-lzmadec \
--disable-lzmainfo \
--disable-lzma-links \
--disable-scripts \
--disable-doc \
--host="${host}" \
--prefix="${install_path}"
make MACOSX_DEPLOYMENT_TARGET="${deployment_target}" install
popd >/dev/null
"""
)
# language=bash
build_universal_and_install_command = Template(
"""
lipo -create -output "${install_lib_path}/liblzma.a" "${arm64_lib_path}/liblzma.a" "${x86_64_lib_path}/liblzma.a"
cp -r "${arm64_include_path}"/* "${install_include_path}"
"""
)

View File

View File

@ -1,21 +0,0 @@
import subprocess
import sys
from pathlib import Path
class ShellExecutionException(Exception):
pass
def shell(command: str, cwd: Path):
with subprocess.Popen(
command, cwd=cwd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
) as proc:
while proc.stdout.readable():
if line := proc.stdout.readline():
sys.stdout.write(line.decode("utf-8"))
else:
break
if proc.wait() != 0:
raise ShellExecutionException(command)

View File

@ -1 +0,0 @@
../.github/workflows

View File

@ -5,6 +5,6 @@
},
"dependencies": {
"vimrDeps": "vimr-deps-2021-12-12",
"nvimServer": "nvimserver-0.7.0-0"
"nvimServer": "nvimserver-0.7.0-1"
}
}

View File

@ -1,7 +1,12 @@
# Next
* Improved trackpad scrolling sensitivity (removed the option for customizing the sensitivity). Thanks @tsung-ju for the PR!
* ...
* Refactor open quickly:
- Use [fzy](https://github.com/jhawthorn/fzy) instead of [ccls](https://github.com/MaskRay/ccls)
- Replace [The Silver Searcher](https://github.com/ggreer/the_silver_searcher)'s ignore mechanism with own implementation in Swift using [wildmatch](https://github.com/davvid/wildmatch)
* Dependencies updates
- Quick/Nimble@10.0.0
- qvacua/misc.swift@0.0.1
# 0.39.0-20220416.182927