mirror of
https://github.com/qvacua/vimr.git
synced 2024-09-11 17:15:34 +03:00
Compare commits
39 Commits
2ea866e694
...
724d305168
Author | SHA1 | Date | |
---|---|---|---|
|
724d305168 | ||
|
0d37f294a0 | ||
|
50d70eb46d | ||
|
17f7ec13bd | ||
|
192d0c9429 | ||
|
800f822626 | ||
|
4d49c15429 | ||
|
f2a2659c36 | ||
|
e34f905f80 | ||
|
1bef38e651 | ||
|
fdb869e010 | ||
|
141109c396 | ||
|
2567204282 | ||
|
f635524b1c | ||
|
9292d751e4 | ||
|
2cd94c7f6f | ||
|
68afcc235c | ||
|
94440566c9 | ||
|
e47cc2f6c2 | ||
|
c4b5a3df1d | ||
|
56be37a1d1 | ||
|
972235ca5b | ||
|
52ae48be2a | ||
|
bf89439ad4 | ||
|
b74dca4092 | ||
|
a23109ec84 | ||
|
048f0ae4a2 | ||
|
2f22869f9a | ||
|
f9931cb083 | ||
|
6c63e7694b | ||
|
23a86134ab | ||
|
db39dcb31e | ||
|
a677419cca | ||
|
fcc2e5c2da | ||
|
16fd05b06f | ||
|
80945855b8 | ||
|
7ffdd3bcd0 | ||
|
688a1c5c5d | ||
|
5c632d5248 |
@ -123,6 +123,8 @@ public extension URL {
|
||||
return self.deletingLastPathComponent()
|
||||
}
|
||||
|
||||
var shellEscapedPath: String { self.path.shellEscapedPath }
|
||||
|
||||
var isDir: Bool { self.resourceValue(URLResourceKey.isDirectoryKey.rawValue) }
|
||||
|
||||
var isHidden: Bool { self.resourceValue(URLResourceKey.isHiddenKey.rawValue) }
|
||||
|
@ -20,6 +20,20 @@ public extension String {
|
||||
let idx = self.index(self.startIndex, offsetBy: prefix.count)
|
||||
return String(self[idx..<self.endIndex])
|
||||
}
|
||||
|
||||
// From https://stackoverflow.com/a/56391610
|
||||
@inlinable
|
||||
@inline(__always)
|
||||
var fullRange: NSRange { NSRange(self.startIndex..., in: self) }
|
||||
|
||||
// From https://stackoverflow.com/a/55560988
|
||||
var shellEscapedPath: String {
|
||||
shellEscapeRegex.stringByReplacingMatches(
|
||||
in: self,
|
||||
range: self.fullRange,
|
||||
withTemplate: "\\\\$1"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
public extension Array where Element: Equatable {
|
||||
@ -99,3 +113,9 @@ public extension Sequence {
|
||||
return self
|
||||
}
|
||||
}
|
||||
|
||||
// From https://stackoverflow.com/a/55560988
|
||||
private let shellEscapeRegex = try! NSRegularExpression(
|
||||
// We know that the following regex is valid.
|
||||
pattern: "([ !\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\,\\:\\;\\<\\=\\>\\?\\[\\]\\`\\{\\|\\}\\~])"
|
||||
)
|
||||
|
18
DEVELOP.md
18
DEVELOP.md
@ -44,7 +44,7 @@ then continuously invoke the `build_nvimserver_for_local_dev` script.
|
||||
create a release and upload it.
|
||||
* Build the `arm64` version locally and upload it:
|
||||
```bash
|
||||
download_gettext=true clean=true build_libnvim=true ./NvimServer/bin/build_nvimserver.sh
|
||||
clean=true build_libnvim=true ./NvimServer/bin/build_nvimserver.sh
|
||||
```
|
||||
* Build a universal binary by the following and upload the artefact:
|
||||
```bash
|
||||
@ -63,20 +63,20 @@ then continuously invoke the `build_nvimserver_for_local_dev` script.
|
||||
|
||||
* Set a new version of VimR via
|
||||
```bash
|
||||
is_snapshot=true ./bin/set_new_versions.sh
|
||||
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 print out some environment variables you can use when invoking the
|
||||
`build_release.sh` script later.
|
||||
and commit. This will create a `${bundle_version}-snapshot/release.sh` file to be used
|
||||
with `build_release.sh`.
|
||||
* Tag with the name
|
||||
- Snapshot: `snapshot/yyyymmdd.HHMMSS`
|
||||
- Release: `vX.Y.Z-yyyymmdd.HHMMSS`
|
||||
* Push, create a release and add release notes.
|
||||
* Push
|
||||
* Build, package and upload via
|
||||
```bash
|
||||
is_snapshot=true \
|
||||
bundle_version=20211212.213543 tag=snapshot/20211212.213543 marketing_version=SNAPSHOT-20211212.213543 \
|
||||
upload=true update_appcast=true \
|
||||
create_gh_release=true upload=true update_appcast=true \
|
||||
release_spec_file=....sh \
|
||||
./bin/build_release.sh
|
||||
```
|
||||
* The `appcast{-snapshot}.xml` file is modified. Check and push.
|
||||
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit d6cee7824734cf82a8d72ab8305d2ac8a35a37b9
|
||||
Subproject commit f42fde64d27b4e4470159cf54440c6c6c0f72907
|
@ -1,4 +1,4 @@
|
||||
// Auto generated for nvim v0.6.1
|
||||
// Auto generated for nvim v0.7.0
|
||||
// See bin/generate_autocmds.py
|
||||
|
||||
enum NvimAutoCommandEvent: Int {
|
||||
@ -43,81 +43,86 @@ enum NvimAutoCommandEvent: Int {
|
||||
case diagnosticchanged = 37
|
||||
case diffupdated = 38
|
||||
case dirchanged = 39
|
||||
case encodingchanged = 40
|
||||
case exitpre = 41
|
||||
case fileappendcmd = 42
|
||||
case fileappendpost = 43
|
||||
case fileappendpre = 44
|
||||
case filechangedro = 45
|
||||
case filechangedshell = 46
|
||||
case filechangedshellpost = 47
|
||||
case filereadcmd = 48
|
||||
case filereadpost = 49
|
||||
case filereadpre = 50
|
||||
case filetype = 51
|
||||
case filewritecmd = 52
|
||||
case filewritepost = 53
|
||||
case filewritepre = 54
|
||||
case filterreadpost = 55
|
||||
case filterreadpre = 56
|
||||
case filterwritepost = 57
|
||||
case filterwritepre = 58
|
||||
case focusgained = 59
|
||||
case focuslost = 60
|
||||
case funcundefined = 61
|
||||
case guienter = 62
|
||||
case guifailed = 63
|
||||
case insertchange = 64
|
||||
case insertcharpre = 65
|
||||
case insertenter = 66
|
||||
case insertleave = 67
|
||||
case insertleavepre = 68
|
||||
case menupopup = 69
|
||||
case optionset = 70
|
||||
case quickfixcmdpost = 71
|
||||
case quickfixcmdpre = 72
|
||||
case quitpre = 73
|
||||
case remotereply = 74
|
||||
case sessionloadpost = 75
|
||||
case shellcmdpost = 76
|
||||
case shellfilterpost = 77
|
||||
case signal = 78
|
||||
case sourcecmd = 79
|
||||
case sourcepost = 80
|
||||
case sourcepre = 81
|
||||
case spellfilemissing = 82
|
||||
case stdinreadpost = 83
|
||||
case stdinreadpre = 84
|
||||
case swapexists = 85
|
||||
case syntax = 86
|
||||
case tabclosed = 87
|
||||
case tabenter = 88
|
||||
case tableave = 89
|
||||
case tabnew = 90
|
||||
case tabnewentered = 91
|
||||
case termchanged = 92
|
||||
case termclose = 93
|
||||
case termenter = 94
|
||||
case termleave = 95
|
||||
case termopen = 96
|
||||
case termresponse = 97
|
||||
case textchanged = 98
|
||||
case textchangedi = 99
|
||||
case textchangedp = 100
|
||||
case textyankpost = 101
|
||||
case uienter = 102
|
||||
case uileave = 103
|
||||
case user = 104
|
||||
case vimenter = 105
|
||||
case vimleave = 106
|
||||
case vimleavepre = 107
|
||||
case vimresized = 108
|
||||
case vimresume = 109
|
||||
case vimsuspend = 110
|
||||
case winclosed = 111
|
||||
case winenter = 112
|
||||
case winleave = 113
|
||||
case winnew = 114
|
||||
case winscrolled = 115
|
||||
case dirchangedpre = 40
|
||||
case encodingchanged = 41
|
||||
case exitpre = 42
|
||||
case fileappendcmd = 43
|
||||
case fileappendpost = 44
|
||||
case fileappendpre = 45
|
||||
case filechangedro = 46
|
||||
case filechangedshell = 47
|
||||
case filechangedshellpost = 48
|
||||
case filereadcmd = 49
|
||||
case filereadpost = 50
|
||||
case filereadpre = 51
|
||||
case filetype = 52
|
||||
case filewritecmd = 53
|
||||
case filewritepost = 54
|
||||
case filewritepre = 55
|
||||
case filterreadpost = 56
|
||||
case filterreadpre = 57
|
||||
case filterwritepost = 58
|
||||
case filterwritepre = 59
|
||||
case focusgained = 60
|
||||
case focuslost = 61
|
||||
case funcundefined = 62
|
||||
case guienter = 63
|
||||
case guifailed = 64
|
||||
case insertchange = 65
|
||||
case insertcharpre = 66
|
||||
case insertenter = 67
|
||||
case insertleave = 68
|
||||
case insertleavepre = 69
|
||||
case menupopup = 70
|
||||
case modechanged = 71
|
||||
case optionset = 72
|
||||
case quickfixcmdpost = 73
|
||||
case quickfixcmdpre = 74
|
||||
case quitpre = 75
|
||||
case recordingenter = 76
|
||||
case recordingleave = 77
|
||||
case remotereply = 78
|
||||
case searchwrapped = 79
|
||||
case sessionloadpost = 80
|
||||
case shellcmdpost = 81
|
||||
case shellfilterpost = 82
|
||||
case signal = 83
|
||||
case sourcecmd = 84
|
||||
case sourcepost = 85
|
||||
case sourcepre = 86
|
||||
case spellfilemissing = 87
|
||||
case stdinreadpost = 88
|
||||
case stdinreadpre = 89
|
||||
case swapexists = 90
|
||||
case syntax = 91
|
||||
case tabclosed = 92
|
||||
case tabenter = 93
|
||||
case tableave = 94
|
||||
case tabnew = 95
|
||||
case tabnewentered = 96
|
||||
case termchanged = 97
|
||||
case termclose = 98
|
||||
case termenter = 99
|
||||
case termleave = 100
|
||||
case termopen = 101
|
||||
case termresponse = 102
|
||||
case textchanged = 103
|
||||
case textchangedi = 104
|
||||
case textchangedp = 105
|
||||
case textyankpost = 106
|
||||
case uienter = 107
|
||||
case uileave = 108
|
||||
case user = 109
|
||||
case vimenter = 110
|
||||
case vimleave = 111
|
||||
case vimleavepre = 112
|
||||
case vimresized = 113
|
||||
case vimresume = 114
|
||||
case vimsuspend = 115
|
||||
case winclosed = 116
|
||||
case winenter = 117
|
||||
case winleave = 118
|
||||
case winnew = 119
|
||||
case winscrolled = 120
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Auto generated for nvim v0.6.1
|
||||
// Auto generated for nvim v0.7.0
|
||||
// See bin/generate_cursor_shape.py
|
||||
|
||||
public enum CursorModeShape: UInt {
|
||||
|
@ -154,7 +154,7 @@ public extension NvimView {
|
||||
|
||||
func saveCurrentTab(url: URL) -> Completable {
|
||||
self.api
|
||||
.command(command: "w \(url.path)")
|
||||
.command(command: "w \(url.shellEscapedPath)")
|
||||
.subscribe(on:self.scheduler)
|
||||
}
|
||||
|
||||
@ -222,7 +222,7 @@ public extension NvimView {
|
||||
|
||||
private func open(_ url: URL, cmd: String) -> Completable {
|
||||
self.api
|
||||
.command(command: "\(cmd) \(url.path)")
|
||||
.command(command: "\(cmd) \(url.shellEscapedPath)")
|
||||
.subscribe(on:self.scheduler)
|
||||
}
|
||||
|
||||
|
@ -25,10 +25,20 @@ extension NvimView {
|
||||
return
|
||||
}
|
||||
|
||||
// When both anti-aliasing and font smoothing is turned on,
|
||||
// then the "Use LCD font smoothing when available" setting is used
|
||||
// to render texts, cf. chapter 11 from "Programming with Quartz".
|
||||
context.setShouldSmoothFonts(true)
|
||||
// See chapter 11 from "Programming with Quartz".
|
||||
switch self.fontSmoothing {
|
||||
case .noAntiAliasing:
|
||||
context.setShouldAntialias(false)
|
||||
context.setShouldSmoothFonts(false)
|
||||
case .noFontSmoothing:
|
||||
context.setShouldAntialias(true)
|
||||
context.setShouldSmoothFonts(false)
|
||||
case .withFontSmoothing:
|
||||
context.setShouldAntialias(true)
|
||||
context.setShouldSmoothFonts(true)
|
||||
case .systemSetting:
|
||||
break
|
||||
}
|
||||
context.setTextDrawingMode(.fill)
|
||||
|
||||
let dirtyRects = self.rectsBeingDrawn()
|
||||
|
@ -76,7 +76,11 @@ extension NvimView {
|
||||
.andThen(self.api.run(at: sockPath))
|
||||
.andThen(
|
||||
self.sourceFileUrls.reduce(Completable.empty()) { prev, url in
|
||||
prev.andThen(self.api.exec(src: "source \(url.path)", output: true).asCompletable())
|
||||
prev
|
||||
.andThen(
|
||||
self.api.exec(src: "source \(url.shellEscapedPath)", output: true)
|
||||
.asCompletable()
|
||||
)
|
||||
}
|
||||
)
|
||||
.andThen(self.api.subscribe(event: NvimView.rpcEventName))
|
||||
|
@ -206,7 +206,7 @@ extension NvimView {
|
||||
let loadGinit = FileManager.default.fileExists(atPath: ginitPath)
|
||||
if loadGinit {
|
||||
self.bridgeLogger.debug("Source'ing ginit.vim")
|
||||
return self.api.command(command: "source \(ginitPath)")
|
||||
return self.api.command(command: "source \(ginitPath.shellEscapedPath)")
|
||||
} else {
|
||||
return .empty()
|
||||
}
|
||||
|
@ -12,6 +12,13 @@ import RxPack
|
||||
import RxSwift
|
||||
import Tabs
|
||||
|
||||
public enum FontSmoothing: String, Codable, CaseIterable {
|
||||
case systemSetting
|
||||
case withFontSmoothing
|
||||
case noFontSmoothing
|
||||
case noAntiAliasing
|
||||
}
|
||||
|
||||
public protocol NvimViewDelegate: AnyObject {
|
||||
func isMenuItemKeyEquivalent(_: NSEvent) -> Bool
|
||||
}
|
||||
@ -63,6 +70,10 @@ public class NvimView: NSView,
|
||||
}
|
||||
}
|
||||
|
||||
public var fontSmoothing = FontSmoothing.systemSetting {
|
||||
didSet { self.markForRenderWholeView() }
|
||||
}
|
||||
|
||||
public var drawsParallel = false {
|
||||
didSet { self.drawer.drawsParallel = self.drawsParallel }
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Auto generated for nvim version 0.6.1.
|
||||
// Auto generated for nvim version 0.7.0.
|
||||
// See bin/generate_api_methods.py
|
||||
|
||||
import Foundation
|
||||
@ -41,6 +41,212 @@ extension RxNeovimApi {
|
||||
|
||||
extension RxNeovimApi {
|
||||
|
||||
public func getAutocmds(
|
||||
opts: Dictionary<String, RxNeovimApi.Value>,
|
||||
errWhenBlocked: Bool = true
|
||||
) -> Single<RxNeovimApi.Value> {
|
||||
|
||||
let params: [RxNeovimApi.Value] = [
|
||||
.map(opts.mapToDict({ (Value.string($0), $1) })),
|
||||
]
|
||||
|
||||
func transform(_ value: Value) throws -> RxNeovimApi.Value {
|
||||
guard let result = (Optional(value)) else {
|
||||
throw RxNeovimApi.Error.conversion(type: RxNeovimApi.Value.self)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
if errWhenBlocked {
|
||||
return self
|
||||
.checkBlocked(
|
||||
self.rpc(method: "nvim_get_autocmds", params: params, expectsReturnValue: true)
|
||||
)
|
||||
.map(transform)
|
||||
}
|
||||
|
||||
return self
|
||||
.rpc(method: "nvim_get_autocmds", params: params, expectsReturnValue: true)
|
||||
.map(transform)
|
||||
}
|
||||
|
||||
public func createAutocmd(
|
||||
event: RxNeovimApi.Value,
|
||||
opts: Dictionary<String, RxNeovimApi.Value>,
|
||||
errWhenBlocked: Bool = true
|
||||
) -> Single<Int> {
|
||||
|
||||
let params: [RxNeovimApi.Value] = [
|
||||
event,
|
||||
.map(opts.mapToDict({ (Value.string($0), $1) })),
|
||||
]
|
||||
|
||||
func transform(_ value: Value) throws -> Int {
|
||||
guard let result = ((value.int64Value == nil ? nil : Int(value.int64Value!))) else {
|
||||
throw RxNeovimApi.Error.conversion(type: Int.self)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
if errWhenBlocked {
|
||||
return self
|
||||
.checkBlocked(
|
||||
self.rpc(method: "nvim_create_autocmd", params: params, expectsReturnValue: true)
|
||||
)
|
||||
.map(transform)
|
||||
}
|
||||
|
||||
return self
|
||||
.rpc(method: "nvim_create_autocmd", params: params, expectsReturnValue: true)
|
||||
.map(transform)
|
||||
}
|
||||
|
||||
public func delAutocmd(
|
||||
id: Int,
|
||||
expectsReturnValue: Bool = false
|
||||
) -> Completable {
|
||||
|
||||
let params: [RxNeovimApi.Value] = [
|
||||
.int(Int64(id)),
|
||||
]
|
||||
|
||||
if expectsReturnValue {
|
||||
return self
|
||||
.checkBlocked(
|
||||
self.rpc(method: "nvim_del_autocmd", params: params, expectsReturnValue: expectsReturnValue)
|
||||
)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
return self
|
||||
.rpc(method: "nvim_del_autocmd", params: params, expectsReturnValue: expectsReturnValue)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
public func clearAutocmds(
|
||||
opts: Dictionary<String, RxNeovimApi.Value>,
|
||||
expectsReturnValue: Bool = false
|
||||
) -> Completable {
|
||||
|
||||
let params: [RxNeovimApi.Value] = [
|
||||
.map(opts.mapToDict({ (Value.string($0), $1) })),
|
||||
]
|
||||
|
||||
if expectsReturnValue {
|
||||
return self
|
||||
.checkBlocked(
|
||||
self.rpc(method: "nvim_clear_autocmds", params: params, expectsReturnValue: expectsReturnValue)
|
||||
)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
return self
|
||||
.rpc(method: "nvim_clear_autocmds", params: params, expectsReturnValue: expectsReturnValue)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
public func createAugroup(
|
||||
name: String,
|
||||
opts: Dictionary<String, RxNeovimApi.Value>,
|
||||
errWhenBlocked: Bool = true
|
||||
) -> Single<Int> {
|
||||
|
||||
let params: [RxNeovimApi.Value] = [
|
||||
.string(name),
|
||||
.map(opts.mapToDict({ (Value.string($0), $1) })),
|
||||
]
|
||||
|
||||
func transform(_ value: Value) throws -> Int {
|
||||
guard let result = ((value.int64Value == nil ? nil : Int(value.int64Value!))) else {
|
||||
throw RxNeovimApi.Error.conversion(type: Int.self)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
if errWhenBlocked {
|
||||
return self
|
||||
.checkBlocked(
|
||||
self.rpc(method: "nvim_create_augroup", params: params, expectsReturnValue: true)
|
||||
)
|
||||
.map(transform)
|
||||
}
|
||||
|
||||
return self
|
||||
.rpc(method: "nvim_create_augroup", params: params, expectsReturnValue: true)
|
||||
.map(transform)
|
||||
}
|
||||
|
||||
public func delAugroupById(
|
||||
id: Int,
|
||||
expectsReturnValue: Bool = false
|
||||
) -> Completable {
|
||||
|
||||
let params: [RxNeovimApi.Value] = [
|
||||
.int(Int64(id)),
|
||||
]
|
||||
|
||||
if expectsReturnValue {
|
||||
return self
|
||||
.checkBlocked(
|
||||
self.rpc(method: "nvim_del_augroup_by_id", params: params, expectsReturnValue: expectsReturnValue)
|
||||
)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
return self
|
||||
.rpc(method: "nvim_del_augroup_by_id", params: params, expectsReturnValue: expectsReturnValue)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
public func delAugroupByName(
|
||||
name: String,
|
||||
expectsReturnValue: Bool = false
|
||||
) -> Completable {
|
||||
|
||||
let params: [RxNeovimApi.Value] = [
|
||||
.string(name),
|
||||
]
|
||||
|
||||
if expectsReturnValue {
|
||||
return self
|
||||
.checkBlocked(
|
||||
self.rpc(method: "nvim_del_augroup_by_name", params: params, expectsReturnValue: expectsReturnValue)
|
||||
)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
return self
|
||||
.rpc(method: "nvim_del_augroup_by_name", params: params, expectsReturnValue: expectsReturnValue)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
public func execAutocmds(
|
||||
event: RxNeovimApi.Value,
|
||||
opts: Dictionary<String, RxNeovimApi.Value>,
|
||||
expectsReturnValue: Bool = false
|
||||
) -> Completable {
|
||||
|
||||
let params: [RxNeovimApi.Value] = [
|
||||
event,
|
||||
.map(opts.mapToDict({ (Value.string($0), $1) })),
|
||||
]
|
||||
|
||||
if expectsReturnValue {
|
||||
return self
|
||||
.checkBlocked(
|
||||
self.rpc(method: "nvim_exec_autocmds", params: params, expectsReturnValue: expectsReturnValue)
|
||||
)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
return self
|
||||
.rpc(method: "nvim_exec_autocmds", params: params, expectsReturnValue: expectsReturnValue)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
public func bufLineCount(
|
||||
buffer: RxNeovimApi.Buffer,
|
||||
errWhenBlocked: Bool = true
|
||||
@ -233,6 +439,46 @@ extension RxNeovimApi {
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
public func bufGetText(
|
||||
buffer: RxNeovimApi.Buffer,
|
||||
start_row: Int,
|
||||
start_col: Int,
|
||||
end_row: Int,
|
||||
end_col: Int,
|
||||
opts: Dictionary<String, RxNeovimApi.Value>,
|
||||
errWhenBlocked: Bool = true
|
||||
) -> Single<[String]> {
|
||||
|
||||
let params: [RxNeovimApi.Value] = [
|
||||
.int(Int64(buffer.handle)),
|
||||
.int(Int64(start_row)),
|
||||
.int(Int64(start_col)),
|
||||
.int(Int64(end_row)),
|
||||
.int(Int64(end_col)),
|
||||
.map(opts.mapToDict({ (Value.string($0), $1) })),
|
||||
]
|
||||
|
||||
func transform(_ value: Value) throws -> [String] {
|
||||
guard let result = (value.arrayValue?.compactMap({ v in v.stringValue })) else {
|
||||
throw RxNeovimApi.Error.conversion(type: [String].self)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
if errWhenBlocked {
|
||||
return self
|
||||
.checkBlocked(
|
||||
self.rpc(method: "nvim_buf_get_text", params: params, expectsReturnValue: true)
|
||||
)
|
||||
.map(transform)
|
||||
}
|
||||
|
||||
return self
|
||||
.rpc(method: "nvim_buf_get_text", params: params, expectsReturnValue: true)
|
||||
.map(transform)
|
||||
}
|
||||
|
||||
public func bufGetOffset(
|
||||
buffer: RxNeovimApi.Buffer,
|
||||
index: Int,
|
||||
@ -827,6 +1073,58 @@ extension RxNeovimApi {
|
||||
.map(transform)
|
||||
}
|
||||
|
||||
public func bufCreateUserCommand(
|
||||
buffer: RxNeovimApi.Buffer,
|
||||
name: String,
|
||||
command: RxNeovimApi.Value,
|
||||
opts: Dictionary<String, RxNeovimApi.Value>,
|
||||
expectsReturnValue: Bool = false
|
||||
) -> Completable {
|
||||
|
||||
let params: [RxNeovimApi.Value] = [
|
||||
.int(Int64(buffer.handle)),
|
||||
.string(name),
|
||||
command,
|
||||
.map(opts.mapToDict({ (Value.string($0), $1) })),
|
||||
]
|
||||
|
||||
if expectsReturnValue {
|
||||
return self
|
||||
.checkBlocked(
|
||||
self.rpc(method: "nvim_buf_create_user_command", params: params, expectsReturnValue: expectsReturnValue)
|
||||
)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
return self
|
||||
.rpc(method: "nvim_buf_create_user_command", params: params, expectsReturnValue: expectsReturnValue)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
public func bufDelUserCommand(
|
||||
buffer: RxNeovimApi.Buffer,
|
||||
name: String,
|
||||
expectsReturnValue: Bool = false
|
||||
) -> Completable {
|
||||
|
||||
let params: [RxNeovimApi.Value] = [
|
||||
.int(Int64(buffer.handle)),
|
||||
.string(name),
|
||||
]
|
||||
|
||||
if expectsReturnValue {
|
||||
return self
|
||||
.checkBlocked(
|
||||
self.rpc(method: "nvim_buf_del_user_command", params: params, expectsReturnValue: expectsReturnValue)
|
||||
)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
return self
|
||||
.rpc(method: "nvim_buf_del_user_command", params: params, expectsReturnValue: expectsReturnValue)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
public func createNamespace(
|
||||
name: String,
|
||||
errWhenBlocked: Bool = true
|
||||
@ -1620,14 +1918,14 @@ extension RxNeovimApi {
|
||||
public func feedkeys(
|
||||
keys: String,
|
||||
mode: String,
|
||||
escape_csi: Bool,
|
||||
escape_ks: Bool,
|
||||
expectsReturnValue: Bool = false
|
||||
) -> Completable {
|
||||
|
||||
let params: [RxNeovimApi.Value] = [
|
||||
.string(keys),
|
||||
.string(mode),
|
||||
.bool(escape_csi),
|
||||
.bool(escape_ks),
|
||||
]
|
||||
|
||||
if expectsReturnValue {
|
||||
@ -2152,6 +2450,64 @@ extension RxNeovimApi {
|
||||
.map(transform)
|
||||
}
|
||||
|
||||
public func getOptionValue(
|
||||
name: String,
|
||||
opts: Dictionary<String, RxNeovimApi.Value>,
|
||||
errWhenBlocked: Bool = true
|
||||
) -> Single<RxNeovimApi.Value> {
|
||||
|
||||
let params: [RxNeovimApi.Value] = [
|
||||
.string(name),
|
||||
.map(opts.mapToDict({ (Value.string($0), $1) })),
|
||||
]
|
||||
|
||||
func transform(_ value: Value) throws -> RxNeovimApi.Value {
|
||||
guard let result = (Optional(value)) else {
|
||||
throw RxNeovimApi.Error.conversion(type: RxNeovimApi.Value.self)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
if errWhenBlocked {
|
||||
return self
|
||||
.checkBlocked(
|
||||
self.rpc(method: "nvim_get_option_value", params: params, expectsReturnValue: true)
|
||||
)
|
||||
.map(transform)
|
||||
}
|
||||
|
||||
return self
|
||||
.rpc(method: "nvim_get_option_value", params: params, expectsReturnValue: true)
|
||||
.map(transform)
|
||||
}
|
||||
|
||||
public func setOptionValue(
|
||||
name: String,
|
||||
value: RxNeovimApi.Value,
|
||||
opts: Dictionary<String, RxNeovimApi.Value>,
|
||||
expectsReturnValue: Bool = false
|
||||
) -> Completable {
|
||||
|
||||
let params: [RxNeovimApi.Value] = [
|
||||
.string(name),
|
||||
value,
|
||||
.map(opts.mapToDict({ (Value.string($0), $1) })),
|
||||
]
|
||||
|
||||
if expectsReturnValue {
|
||||
return self
|
||||
.checkBlocked(
|
||||
self.rpc(method: "nvim_set_option_value", params: params, expectsReturnValue: expectsReturnValue)
|
||||
)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
return self
|
||||
.rpc(method: "nvim_set_option_value", params: params, expectsReturnValue: expectsReturnValue)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
public func getAllOptionsInfo(
|
||||
errWhenBlocked: Bool = true
|
||||
) -> Single<Dictionary<String, RxNeovimApi.Value>> {
|
||||
@ -3368,6 +3724,54 @@ extension RxNeovimApi {
|
||||
.map(transform)
|
||||
}
|
||||
|
||||
public func createUserCommand(
|
||||
name: String,
|
||||
command: RxNeovimApi.Value,
|
||||
opts: Dictionary<String, RxNeovimApi.Value>,
|
||||
expectsReturnValue: Bool = false
|
||||
) -> Completable {
|
||||
|
||||
let params: [RxNeovimApi.Value] = [
|
||||
.string(name),
|
||||
command,
|
||||
.map(opts.mapToDict({ (Value.string($0), $1) })),
|
||||
]
|
||||
|
||||
if expectsReturnValue {
|
||||
return self
|
||||
.checkBlocked(
|
||||
self.rpc(method: "nvim_create_user_command", params: params, expectsReturnValue: expectsReturnValue)
|
||||
)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
return self
|
||||
.rpc(method: "nvim_create_user_command", params: params, expectsReturnValue: expectsReturnValue)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
public func delUserCommand(
|
||||
name: String,
|
||||
expectsReturnValue: Bool = false
|
||||
) -> Completable {
|
||||
|
||||
let params: [RxNeovimApi.Value] = [
|
||||
.string(name),
|
||||
]
|
||||
|
||||
if expectsReturnValue {
|
||||
return self
|
||||
.checkBlocked(
|
||||
self.rpc(method: "nvim_del_user_command", params: params, expectsReturnValue: expectsReturnValue)
|
||||
)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
return self
|
||||
.rpc(method: "nvim_del_user_command", params: params, expectsReturnValue: expectsReturnValue)
|
||||
.asCompletable()
|
||||
}
|
||||
|
||||
public func exec(
|
||||
src: String,
|
||||
output: Bool,
|
||||
|
@ -1 +1 @@
|
||||
v0.6.1
|
||||
nightly
|
||||
|
@ -1153,7 +1153,7 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 20220322.180037;
|
||||
CURRENT_PROJECT_VERSION = 20220416.182927;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
@ -1214,7 +1214,7 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 20220322.180037;
|
||||
CURRENT_PROJECT_VERSION = 20220416.182927;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
@ -1243,7 +1243,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 20220322.180037;
|
||||
CURRENT_PROJECT_VERSION = 20220416.182927;
|
||||
DEFINES_MODULE = YES;
|
||||
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/.deps/include";
|
||||
IBC_MODULE = VimR;
|
||||
@ -1271,7 +1271,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 20220322.180037;
|
||||
CURRENT_PROJECT_VERSION = 20220416.182927;
|
||||
DEFINES_MODULE = YES;
|
||||
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/.deps/include";
|
||||
IBC_MODULE = VimR;
|
||||
|
@ -19,6 +19,7 @@ class AppearancePref: PrefPane, NSComboBoxDelegate, NSControlTextEditingDelegate
|
||||
case setFont(NSFont)
|
||||
case setLinespacing(CGFloat)
|
||||
case setCharacterspacing(CGFloat)
|
||||
case setFontSmoothing(FontSmoothing)
|
||||
}
|
||||
|
||||
override var displayName: String { "Appearance" }
|
||||
@ -44,6 +45,7 @@ class AppearancePref: PrefPane, NSComboBoxDelegate, NSControlTextEditingDelegate
|
||||
self.usesColorscheme = state.mainWindowTemplate.appearance.usesTheme
|
||||
self.showsFileIcon = state.mainWindowTemplate.appearance.showsFileIcon
|
||||
self.usesCustomTab = state.mainWindowTemplate.appearance.usesCustomTab
|
||||
self.fontSmoothing = state.mainWindowTemplate.appearance.fontSmoothing
|
||||
|
||||
super.init(frame: .zero)
|
||||
|
||||
@ -60,6 +62,7 @@ class AppearancePref: PrefPane, NSComboBoxDelegate, NSControlTextEditingDelegate
|
||||
guard self.font != appearance.font
|
||||
|| self.linespacing != appearance.linespacing
|
||||
|| self.characterspacing != appearance.characterspacing
|
||||
|| self.fontSmoothing != appearance.fontSmoothing
|
||||
|| self.usesLigatures != appearance.usesLigatures
|
||||
|| self.usesColorscheme != appearance.usesTheme
|
||||
|| self.showsFileIcon != appearance.showsFileIcon
|
||||
@ -68,6 +71,7 @@ class AppearancePref: PrefPane, NSComboBoxDelegate, NSControlTextEditingDelegate
|
||||
self.font = appearance.font
|
||||
self.linespacing = appearance.linespacing
|
||||
self.characterspacing = appearance.characterspacing
|
||||
self.fontSmoothing = appearance.fontSmoothing
|
||||
self.usesLigatures = appearance.usesLigatures
|
||||
self.usesColorscheme = appearance.usesTheme
|
||||
self.showsFileIcon = appearance.showsFileIcon
|
||||
@ -87,6 +91,7 @@ class AppearancePref: PrefPane, NSComboBoxDelegate, NSControlTextEditingDelegate
|
||||
private var usesColorscheme: Bool
|
||||
private var showsFileIcon: Bool
|
||||
private var usesCustomTab: Bool
|
||||
private var fontSmoothing: FontSmoothing
|
||||
|
||||
private let customTabCheckbox = NSButton(forAutoLayout: ())
|
||||
private let colorschemeCheckbox = NSButton(forAutoLayout: ())
|
||||
@ -94,6 +99,7 @@ class AppearancePref: PrefPane, NSComboBoxDelegate, NSControlTextEditingDelegate
|
||||
private let fontPanelButton = NSButton(forAutoLayout: ())
|
||||
private let linespacingField = NSTextField(forAutoLayout: ())
|
||||
private let characterspacingField = NSTextField(forAutoLayout: ())
|
||||
private let fontSmoothingPopup = NSPopUpButton(forAutoLayout: ())
|
||||
private let ligatureCheckbox = NSButton(forAutoLayout: ())
|
||||
private let previewArea = NSTextView(frame: .zero)
|
||||
|
||||
@ -173,6 +179,17 @@ class AppearancePref: PrefPane, NSComboBoxDelegate, NSControlTextEditingDelegate
|
||||
action: #selector(AppearancePref.usesLigaturesAction(_:))
|
||||
)
|
||||
|
||||
let fontSmoothingPopup = self.fontSmoothingPopup
|
||||
let fontSmoothingTitle = self.titleTextField(title: "Font Smoothing:")
|
||||
fontSmoothingPopup.target = self
|
||||
fontSmoothingPopup.action = #selector(AppearancePref.fontSmoothingAction)
|
||||
fontSmoothingPopup.addItems(withTitles: self.fontSmoothingTitles)
|
||||
let fontSmoothingInfo = self.infoTextField(markdown: #"""
|
||||
"No Font Smoothing" may result in better rendering for non-Retina displays.\
|
||||
If you're still using Monaco-9pt, choose "No Anti Aliasing" 😀 (you may want\
|
||||
to set character spacing to 1.2 then).
|
||||
"""#)
|
||||
|
||||
let previewArea = self.previewArea
|
||||
previewArea.isEditable = true
|
||||
previewArea.maxSize = CGSize(
|
||||
@ -215,6 +232,9 @@ class AppearancePref: PrefPane, NSComboBoxDelegate, NSControlTextEditingDelegate
|
||||
self.addSubview(characterspacingField)
|
||||
self.addSubview(characterspacingInfo)
|
||||
self.addSubview(ligatureCheckbox)
|
||||
self.addSubview(fontSmoothingTitle)
|
||||
self.addSubview(fontSmoothingPopup)
|
||||
self.addSubview(fontSmoothingInfo)
|
||||
self.addSubview(previewScrollView)
|
||||
|
||||
paneTitle.autoPinEdge(toSuperviewEdge: .top, withInset: 18)
|
||||
@ -281,10 +301,19 @@ class AppearancePref: PrefPane, NSComboBoxDelegate, NSControlTextEditingDelegate
|
||||
characterspacingInfo.autoPinEdge(.left, to: .left, of: characterspacingField)
|
||||
characterspacingInfo.autoPinEdge(.top, to: .bottom, of: characterspacingField, withOffset: 5)
|
||||
|
||||
ligatureCheckbox.autoPinEdge(.top, to: .bottom, of: characterspacingInfo, withOffset: 18)
|
||||
fontSmoothingTitle.autoPinEdge(.right, to: .right, of: characterspacingTitle)
|
||||
fontSmoothingTitle.autoAlignAxis(.baseline, toSameAxisOf: fontSmoothingPopup)
|
||||
|
||||
fontSmoothingPopup.autoPinEdge(.top, to: .bottom, of: characterspacingInfo, withOffset: 18)
|
||||
fontSmoothingPopup.autoPinEdge(.left, to: .right, of: fontSmoothingTitle, withOffset: 5)
|
||||
|
||||
fontSmoothingInfo.autoPinEdge(.left, to: .left, of: fontSmoothingPopup)
|
||||
fontSmoothingInfo.autoPinEdge(.top, to: .bottom, of: fontSmoothingPopup, withOffset: 5)
|
||||
|
||||
ligatureCheckbox.autoPinEdge(.top, to: .bottom, of: fontSmoothingInfo, withOffset: 18)
|
||||
ligatureCheckbox.autoPinEdge(.left, to: .right, of: fontTitle, withOffset: 5)
|
||||
|
||||
previewScrollView.autoSetDimension(.height, toSize: 200, relation: .greaterThanOrEqual)
|
||||
previewScrollView.autoSetDimension(.height, toSize: 120, relation: .greaterThanOrEqual)
|
||||
previewScrollView.autoPinEdge(.top, to: .bottom, of: ligatureCheckbox, withOffset: 18)
|
||||
previewScrollView.autoPinEdge(toSuperviewEdge: .right, withInset: 18)
|
||||
previewScrollView.autoPinEdge(toSuperviewEdge: .bottom, withInset: 18)
|
||||
@ -298,6 +327,7 @@ class AppearancePref: PrefPane, NSComboBoxDelegate, NSControlTextEditingDelegate
|
||||
self.linespacingField.stringValue = String(format: "%.2f", self.linespacing)
|
||||
self.characterspacingField.stringValue = String(format: "%.2f", self.characterspacing)
|
||||
self.ligatureCheckbox.boolState = self.usesLigatures
|
||||
self.fontSmoothingPopup.selectItem(at: self.fontSmoothingToIndex(self.fontSmoothing))
|
||||
self.previewArea.font = self.font
|
||||
self.customTabCheckbox.boolState = self.usesCustomTab
|
||||
self.colorschemeCheckbox.boolState = self.usesColorscheme
|
||||
@ -309,6 +339,34 @@ class AppearancePref: PrefPane, NSComboBoxDelegate, NSControlTextEditingDelegate
|
||||
self.previewArea.turnOffLigatures(self)
|
||||
}
|
||||
}
|
||||
|
||||
// Keep the index in sync with indexToFontSmoothing() and fontSmoothingToIndex().
|
||||
private let fontSmoothingTitles = [
|
||||
"System Setting",
|
||||
"With Font Smoothing",
|
||||
"No Font Smoothing",
|
||||
"No Anti Aliasing",
|
||||
]
|
||||
|
||||
private func indexToFontSmoothing(_ index: Int) -> FontSmoothing {
|
||||
switch index {
|
||||
case 0: return .systemSetting
|
||||
case 1: return .withFontSmoothing
|
||||
case 2: return .noFontSmoothing
|
||||
case 3: return .noAntiAliasing
|
||||
|
||||
default: return .systemSetting
|
||||
}
|
||||
}
|
||||
|
||||
private func fontSmoothingToIndex(_ fontSmoothing: FontSmoothing) -> Int {
|
||||
switch fontSmoothing {
|
||||
case .systemSetting: return 0
|
||||
case .withFontSmoothing: return 1
|
||||
case .noFontSmoothing: return 2
|
||||
case .noAntiAliasing: return 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - NSFontChanging
|
||||
@ -350,6 +408,14 @@ extension AppearancePref {
|
||||
self.emit(.setLinespacing(newLinespacing))
|
||||
}
|
||||
|
||||
@objc func fontSmoothingAction(_: NSPopUpButton) {
|
||||
let index = self.fontSmoothingPopup.indexOfSelectedItem
|
||||
|
||||
guard FontSmoothing.allCases.indices.contains(index) else { return }
|
||||
self.fontSmoothing = self.indexToFontSmoothing(index)
|
||||
self.emit(.setFontSmoothing(self.fontSmoothing))
|
||||
}
|
||||
|
||||
private func cappedLinespacing(_ linespacing: Double) -> CGFloat {
|
||||
let cgfLinespacing = linespacing
|
||||
|
||||
|
@ -34,6 +34,9 @@ class AppearancePrefReducer: ReducerType {
|
||||
|
||||
case let .setCharacterspacing(characterspacing):
|
||||
appearance.characterspacing = characterspacing
|
||||
|
||||
case let .setFontSmoothing(fontSmoothing):
|
||||
appearance.fontSmoothing = fontSmoothing
|
||||
}
|
||||
|
||||
self.modify(state: &state, with: appearance)
|
||||
|
@ -35,7 +35,11 @@ class GeneralPref: PrefPane, UiComponent, NSTextFieldDelegate {
|
||||
self.defaultUsesVcsIgnoresCheckbox.boolState = state.openQuickly.defaultUsesVcsIgnores
|
||||
|
||||
self.openFilesFromApplicationsAction = state.openFilesFromApplicationsAction
|
||||
self.openFilesFromApplicationsPopup.selectItem(at: AppState.OpenFilesFromApplicationsAction.allCases.firstIndex(of: state.openFilesFromApplicationsAction) ?? 0)
|
||||
self.openFilesFromApplicationsPopup
|
||||
.selectItem(
|
||||
at: AppState.OpenFilesFromApplicationsAction.allCases
|
||||
.firstIndex(of: state.openFilesFromApplicationsAction) ?? 0
|
||||
)
|
||||
|
||||
self.lastWindowAction = state.afterLastWindowAction
|
||||
self.afterLastWindowPopup
|
||||
@ -53,10 +57,11 @@ class GeneralPref: PrefPane, UiComponent, NSTextFieldDelegate {
|
||||
}
|
||||
|
||||
if self.openFilesFromApplicationsAction != state.openFilesFromApplicationsAction {
|
||||
self.openFilesFromApplicationsPopup.selectItem(
|
||||
at: AppState.OpenFilesFromApplicationsAction.allCases.firstIndex(of: state.openFilesFromApplicationsAction) ?? 0
|
||||
)
|
||||
self.openFilesFromApplicationsAction = state.openFilesFromApplicationsAction
|
||||
self.openFilesFromApplicationsPopup.selectItem(
|
||||
at: AppState.OpenFilesFromApplicationsAction.allCases
|
||||
.firstIndex(of: state.openFilesFromApplicationsAction) ?? 0
|
||||
)
|
||||
self.openFilesFromApplicationsAction = state.openFilesFromApplicationsAction
|
||||
}
|
||||
|
||||
if self.lastWindowAction != state.afterLastWindowAction {
|
||||
@ -110,18 +115,19 @@ class GeneralPref: PrefPane, UiComponent, NSTextFieldDelegate {
|
||||
let onReactivation = self.openOnReactivationCheckbox
|
||||
|
||||
let openFilesFromApplicationsTitle = self.titleTextField(title: "Open files from applications:")
|
||||
openFilesFromApplicationsPopup.target = self
|
||||
openFilesFromApplicationsPopup.action = #selector(GeneralPref.afterOpenFilesFromApplicationsAction)
|
||||
openFilesFromApplicationsPopup.addItems(withTitles: [
|
||||
"In a New Window",
|
||||
"In the Current Window",
|
||||
self.openFilesFromApplicationsPopup.target = self
|
||||
self.openFilesFromApplicationsPopup
|
||||
.action = #selector(GeneralPref.afterOpenFilesFromApplicationsAction)
|
||||
self.openFilesFromApplicationsPopup.addItems(withTitles: [
|
||||
"In a New Window",
|
||||
"In the Current Window",
|
||||
])
|
||||
let openFilesFromApplicationsInfo =
|
||||
self.infoTextField(markdown: #"""
|
||||
This applies to files opened from the Finder \
|
||||
(e.g. by double-clicking on a file or by dragging a file onto the VimR dock icon) \
|
||||
or from external programs such as Xcode.
|
||||
"""#)
|
||||
self.infoTextField(markdown: #"""
|
||||
This applies to files opened from the Finder \
|
||||
(e.g. by double-clicking on a file or by dragging a file onto the VimR dock icon) \
|
||||
or from external programs such as Xcode.
|
||||
"""#)
|
||||
|
||||
let afterLastWindowTitle = self.titleTextField(title: "After Last Window Closes:")
|
||||
let lastWindow = self.afterLastWindowPopup
|
||||
@ -184,7 +190,7 @@ class GeneralPref: PrefPane, UiComponent, NSTextFieldDelegate {
|
||||
self.addSubview(ignoreInfo)
|
||||
|
||||
self.addSubview(openFilesFromApplicationsTitle)
|
||||
self.addSubview(openFilesFromApplicationsPopup)
|
||||
self.addSubview(self.openFilesFromApplicationsPopup)
|
||||
self.addSubview(openFilesFromApplicationsInfo)
|
||||
|
||||
self.addSubview(afterLastWindowTitle)
|
||||
@ -222,14 +228,40 @@ class GeneralPref: PrefPane, UiComponent, NSTextFieldDelegate {
|
||||
relation: .greaterThanOrEqual
|
||||
)
|
||||
|
||||
openFilesFromApplicationsTitle.autoAlignAxis(.baseline, toSameAxisOf: openFilesFromApplicationsPopup)
|
||||
openFilesFromApplicationsTitle.autoAlignAxis(
|
||||
.baseline,
|
||||
toSameAxisOf: self.openFilesFromApplicationsPopup
|
||||
)
|
||||
openFilesFromApplicationsTitle.autoPinEdge(.right, to: .right, of: openUntitledWindowTitle)
|
||||
openFilesFromApplicationsTitle.autoPinEdge(toSuperviewEdge: .left, withInset: 18, relation: .greaterThanOrEqual)
|
||||
openFilesFromApplicationsPopup.autoPinEdge(.top, to: .bottom, of: onReactivation, withOffset: 18)
|
||||
openFilesFromApplicationsPopup.autoPinEdge(.left, to: .right, of: openFilesFromApplicationsTitle, withOffset: 5)
|
||||
openFilesFromApplicationsInfo.autoPinEdge(.top, to: .bottom, of: openFilesFromApplicationsPopup, withOffset: 5)
|
||||
openFilesFromApplicationsTitle.autoPinEdge(
|
||||
toSuperviewEdge: .left,
|
||||
withInset: 18,
|
||||
relation: .greaterThanOrEqual
|
||||
)
|
||||
self.openFilesFromApplicationsPopup.autoPinEdge(
|
||||
.top,
|
||||
to: .bottom,
|
||||
of: onReactivation,
|
||||
withOffset: 18
|
||||
)
|
||||
self.openFilesFromApplicationsPopup.autoPinEdge(
|
||||
.left,
|
||||
to: .right,
|
||||
of: openFilesFromApplicationsTitle,
|
||||
withOffset: 5
|
||||
)
|
||||
openFilesFromApplicationsInfo.autoPinEdge(
|
||||
.top,
|
||||
to: .bottom,
|
||||
of: self.openFilesFromApplicationsPopup,
|
||||
withOffset: 5
|
||||
)
|
||||
openFilesFromApplicationsInfo.autoPinEdge(toSuperviewEdge: .right, withInset: 18)
|
||||
openFilesFromApplicationsInfo.autoPinEdge(.left, to: .left, of: openFilesFromApplicationsPopup)
|
||||
openFilesFromApplicationsInfo.autoPinEdge(
|
||||
.left,
|
||||
to: .left,
|
||||
of: self.openFilesFromApplicationsPopup
|
||||
)
|
||||
|
||||
afterLastWindowTitle.autoAlignAxis(.baseline, toSameAxisOf: lastWindow)
|
||||
afterLastWindowTitle.autoPinEdge(toSuperviewEdge: .left, withInset: 18)
|
||||
@ -334,7 +366,7 @@ extension GeneralPref {
|
||||
let index = sender.indexOfSelectedItem
|
||||
|
||||
guard AppState.OpenFilesFromApplicationsAction.allCases.indices.contains(index) else {
|
||||
return
|
||||
return
|
||||
}
|
||||
self.openFilesFromApplicationsAction = AppState.OpenFilesFromApplicationsAction.allCases[index]
|
||||
self.emit(.setOpenFilesFromApplications(self.openFilesFromApplicationsAction))
|
||||
|
@ -1224,7 +1224,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.38.2</string>
|
||||
<string>0.39.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
@ -1241,7 +1241,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>20220322.180037</string>
|
||||
<string>20220416.182927</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.productivity</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
@ -35,8 +35,8 @@ class MainWindow: NSObject,
|
||||
let neoVimView: NvimView
|
||||
|
||||
var activateAsciiImInInsertMode: Bool {
|
||||
get { self.neoVimView.activateAsciiImInNormalMode }
|
||||
set { self.neoVimView.activateAsciiImInNormalMode = newValue }
|
||||
get { self.neoVimView.activateAsciiImInNormalMode }
|
||||
set { self.neoVimView.activateAsciiImInNormalMode = newValue }
|
||||
}
|
||||
|
||||
weak var shortcutService: ShortcutService?
|
||||
@ -166,6 +166,7 @@ class MainWindow: NSObject,
|
||||
|
||||
self.window.tabbingMode = .disallowed
|
||||
|
||||
self.fontSmoothing = state.appearance.fontSmoothing
|
||||
self.defaultFont = state.appearance.font
|
||||
self.linespacing = state.appearance.linespacing
|
||||
self.characterspacing = state.appearance.characterspacing
|
||||
@ -265,6 +266,7 @@ class MainWindow: NSObject,
|
||||
|
||||
private var goToLineFromCli: Marked<Int>?
|
||||
|
||||
private var fontSmoothing = FontSmoothing.systemSetting
|
||||
private var defaultFont = NvimView.defaultFont
|
||||
private var linespacing = NvimView.defaultLinespacing
|
||||
private var characterspacing = NvimView.defaultCharacterspacing
|
||||
@ -468,7 +470,9 @@ class MainWindow: NSObject,
|
||||
|| self.linespacing != state.appearance.linespacing
|
||||
|| self.characterspacing != state.appearance.characterspacing
|
||||
|| self.usesLigatures != state.appearance.usesLigatures
|
||||
|| self.fontSmoothing != state.appearance.fontSmoothing
|
||||
{
|
||||
self.fontSmoothing = state.appearance.fontSmoothing
|
||||
self.defaultFont = state.appearance.font
|
||||
self.linespacing = state.appearance.linespacing
|
||||
self.characterspacing = state.appearance.characterspacing
|
||||
@ -495,6 +499,7 @@ class MainWindow: NSObject,
|
||||
}
|
||||
|
||||
private func updateNeoVimAppearance() {
|
||||
self.neoVimView.fontSmoothing = self.fontSmoothing
|
||||
self.neoVimView.font = self.defaultFont
|
||||
self.neoVimView.linespacing = self.linespacing
|
||||
self.neoVimView.characterspacing = self.characterspacing
|
||||
|
@ -14,6 +14,7 @@ struct AppState: Codable {
|
||||
case inNewWindow
|
||||
case inCurrentWindow
|
||||
}
|
||||
|
||||
enum AfterLastWindowAction: String, Codable {
|
||||
case doNothing = "do-nothing"
|
||||
case hide
|
||||
@ -79,8 +80,8 @@ struct AppState: Codable {
|
||||
default: .doNothing
|
||||
)
|
||||
self.activateAsciiImInNormalMode = try container.decode(
|
||||
forKey: .activateAsciiImInNormalMode,
|
||||
default: true
|
||||
forKey: .activateAsciiImInNormalMode,
|
||||
default: true
|
||||
)
|
||||
self.useSnapshotUpdate = try container.decode(
|
||||
forKey: .useSnapshotUpdate,
|
||||
@ -198,12 +199,14 @@ struct AppearanceState: Codable {
|
||||
case editorLinespacing = "editor-linespacing"
|
||||
case editorCharacterspacing = "editor-characterspacing"
|
||||
case editorUsesLigatures = "editor-uses-ligatures"
|
||||
case editorFontSmoothing = "editor-font-smoothing"
|
||||
}
|
||||
|
||||
var font = NSFont.userFixedPitchFont(ofSize: 13)!
|
||||
var linespacing: CGFloat = 1
|
||||
var characterspacing: CGFloat = 1
|
||||
var usesLigatures = true
|
||||
var fontSmoothing = FontSmoothing.systemSetting
|
||||
|
||||
var usesCustomTab = true
|
||||
var usesTheme = true
|
||||
@ -231,6 +234,10 @@ struct AppearanceState: Codable {
|
||||
)
|
||||
self.usesLigatures = try container
|
||||
.decodeIfPresent(Bool.self, forKey: .editorUsesLigatures) ?? true
|
||||
self.fontSmoothing = try container.decodeIfPresent(
|
||||
FontSmoothing.self,
|
||||
forKey: .editorFontSmoothing
|
||||
) ?? .systemSetting
|
||||
|
||||
self.usesTheme = try container.decodeIfPresent(Bool.self, forKey: .usesTheme) ?? true
|
||||
self.usesCustomTab = try container.decodeIfPresent(Bool.self, forKey: .usesCustomTab) ?? true
|
||||
@ -247,6 +254,7 @@ struct AppearanceState: Codable {
|
||||
try container.encode(self.font.pointSize, forKey: .editorFontSize)
|
||||
try container.encode(self.linespacing, forKey: .editorLinespacing)
|
||||
try container.encode(self.characterspacing, forKey: .editorCharacterspacing)
|
||||
try container.encode(self.fontSmoothing, forKey: .editorFontSmoothing)
|
||||
try container.encode(self.usesLigatures, forKey: .editorUsesLigatures)
|
||||
}
|
||||
|
||||
|
@ -15,10 +15,10 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.38.2</string>
|
||||
<string>0.39.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>20220322.180037</string>
|
||||
<string>20220416.182927</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
20
appcast.xml
20
appcast.xml
@ -6,24 +6,24 @@
|
||||
<description>Most recent changes with links to updates for VimR.</description>
|
||||
<language>en</language>
|
||||
<item>
|
||||
<title>v0.38.2-20220322.180037</title>
|
||||
<title>v0.39.0-20220416.182927</title>
|
||||
<link>https://twitter.com/vimrefined</link>
|
||||
<sparkle:version>20220322.180037</sparkle:version>
|
||||
<sparkle:shortVersionString>v0.38.2</sparkle:shortVersionString>
|
||||
<sparkle:version>20220416.182927</sparkle:version>
|
||||
<sparkle:shortVersionString>v0.39.0</sparkle:shortVersionString>
|
||||
<description><![CDATA[
|
||||
<ul>
|
||||
<li>GH-923: Bugfix: Input method auto-switch is not handled correctly. Thanks @SolaWing for the PR!</li>
|
||||
<li>Dependencies updates:</li>
|
||||
<li>sparkle-project/Sparkle@2.1.0</li>
|
||||
<li>Neovim 0.7.0 😀</li>
|
||||
<li>GH-922: Add an option to set font smoothing.</li>
|
||||
<li>GH-928: Bugfix: Files containing some special characters in their names cannot be opened.</li>
|
||||
</ul>
|
||||
]]></description>
|
||||
<releaseNotesLink>
|
||||
https://github.com/qvacua/vimr/releases/tag/v0.38.2-20220322.180037
|
||||
https://github.com/qvacua/vimr/releases/tag/v0.39.0-20220416.182927
|
||||
</releaseNotesLink>
|
||||
<pubDate>2022-03-22T18:11:14.469533</pubDate>
|
||||
<pubDate>2022-04-16T18:43:41.274166</pubDate>
|
||||
<minimumSystemVersion>10.13.0</minimumSystemVersion>
|
||||
<enclosure url="https://github.com/qvacua/vimr/releases/download/v0.38.2-20220322.180037/VimR-v0.38.2.tar.bz2"
|
||||
sparkle:edSignature="5BHazAjBSiSSb0AmKoU4VA3+5Vuq6EEfVYi+To8AtRIDDpJQOgsPfO7OfPAjNrQ0l242FB/mnu4rgVjtIkXfBQ==" length="20900652"
|
||||
<enclosure url="https://github.com/qvacua/vimr/releases/download/v0.39.0-20220416.182927/VimR-v0.39.0.tar.bz2"
|
||||
sparkle:edSignature="Q5XobuaNiJUk8pFNsCwT+fUX4DnmHcKuWXosQj3imOb0UHY+EdWhyqgK0ERDQ51pSonerMZxJ0C+nolcCdXfBQ==" length="20982344"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
</channel>
|
||||
|
@ -6,24 +6,24 @@
|
||||
<description>Most recent changes with links to updates for VimR.</description>
|
||||
<language>en</language>
|
||||
<item>
|
||||
<title>v0.38.2-20220322.180037</title>
|
||||
<title>v0.39.0-20220416.182927</title>
|
||||
<link>https://twitter.com/vimrefined</link>
|
||||
<sparkle:version>20220322.180037</sparkle:version>
|
||||
<sparkle:shortVersionString>v0.38.2</sparkle:shortVersionString>
|
||||
<sparkle:version>20220416.182927</sparkle:version>
|
||||
<sparkle:shortVersionString>v0.39.0</sparkle:shortVersionString>
|
||||
<description><![CDATA[
|
||||
<ul>
|
||||
<li>GH-923: Bugfix: Input method auto-switch is not handled correctly. Thanks @SolaWing for the PR!</li>
|
||||
<li>Dependencies updates:</li>
|
||||
<li>sparkle-project/Sparkle@2.1.0</li>
|
||||
<li>Neovim 0.7.0 😀</li>
|
||||
<li>GH-922: Add an option to set font smoothing.</li>
|
||||
<li>GH-928: Bugfix: Files containing some special characters in their names cannot be opened.</li>
|
||||
</ul>
|
||||
]]></description>
|
||||
<releaseNotesLink>
|
||||
https://github.com/qvacua/vimr/releases/tag/v0.38.2-20220322.180037
|
||||
https://github.com/qvacua/vimr/releases/tag/v0.39.0-20220416.182927
|
||||
</releaseNotesLink>
|
||||
<pubDate>2022-03-22T18:11:14.469533</pubDate>
|
||||
<pubDate>2022-04-16T18:43:41.274166</pubDate>
|
||||
<minimumSystemVersion>10.13.0</minimumSystemVersion>
|
||||
<enclosure url="https://github.com/qvacua/vimr/releases/download/v0.38.2-20220322.180037/VimR-v0.38.2.tar.bz2"
|
||||
sparkle:edSignature="5BHazAjBSiSSb0AmKoU4VA3+5Vuq6EEfVYi+To8AtRIDDpJQOgsPfO7OfPAjNrQ0l242FB/mnu4rgVjtIkXfBQ==" length="20900652"
|
||||
<enclosure url="https://github.com/qvacua/vimr/releases/download/v0.39.0-20220416.182927/VimR-v0.39.0.tar.bz2"
|
||||
sparkle:edSignature="Q5XobuaNiJUk8pFNsCwT+fUX4DnmHcKuWXosQj3imOb0UHY+EdWhyqgK0ERDQ51pSonerMZxJ0C+nolcCdXfBQ==" length="20982344"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
</channel>
|
||||
|
@ -1,12 +1,21 @@
|
||||
#!/bin/bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
readonly is_snapshot=${is_snapshot:?"true or false"}
|
||||
readonly bundle_version=${bundle_version:?"date '+%Y%m%d.%H%M%S'"}
|
||||
readonly tag=${tag:?"snapshot/xyz or v0.35.0"}
|
||||
readonly marketing_version=${marketing_version:?"SNAPSHOT-xyz or v0.35.0 (mind the v-prefix when not snapshot"}
|
||||
readonly create_gh_release=${create_gh_release:?"true or false"}
|
||||
readonly upload=${upload:?"true or false"}
|
||||
readonly update_appcast=${update_appcast:?"true or false"}
|
||||
|
||||
# The release spec file should export the following env vars:
|
||||
# is_snapshot
|
||||
# bundle_version
|
||||
# marketing_version
|
||||
# tag
|
||||
# github_release_name
|
||||
# release_notes
|
||||
readonly release_spec_file=${release_spec_file:?"path to release spec sh file (output by set_new_versions.sh script"}
|
||||
|
||||
source "${release_spec_file}"
|
||||
|
||||
readonly build_folder_path="./build/Build/Products/Release"
|
||||
readonly vimr_artifact_path="${build_folder_path}/VimR-${marketing_version}.tar.bz2"
|
||||
declare -r -x GH_REPO="qvacua/vimr"
|
||||
@ -34,7 +43,7 @@ check_version() {
|
||||
fi
|
||||
}
|
||||
|
||||
check_upload() {
|
||||
check_gh_release_present() {
|
||||
if [[ "${upload}" == true ]]; then
|
||||
if gh release list | grep "${tag}"; then
|
||||
echo "Release with tag ${tag} found"
|
||||
@ -57,6 +66,21 @@ build_release() {
|
||||
echo "### Built (signed and notarized) release: ${vimr_artifact_path}"
|
||||
}
|
||||
|
||||
create_gh_release() {
|
||||
if [[ "${is_snapshot}" == true ]]; then
|
||||
gh release create "${tag}" \
|
||||
--discussion-category "general" \
|
||||
--prerelease \
|
||||
--title "${github_release_name}" \
|
||||
--notes "${release_notes}"
|
||||
else
|
||||
gh release create "${tag}" \
|
||||
--discussion-category "general" \
|
||||
--title "${github_release_name}" \
|
||||
--notes "${release_notes}"
|
||||
fi
|
||||
}
|
||||
|
||||
upload_artifact() {
|
||||
local -x GH_TOKEN
|
||||
GH_TOKEN=$(cat ~/.local/secrets/github.qvacua.release.token)
|
||||
@ -86,18 +110,24 @@ update_appcast_file() {
|
||||
}
|
||||
|
||||
main() {
|
||||
echo "is_snapshot=${is_snapshot} bundle_version=${bundle_version}" \
|
||||
"tag=${tag} marketing_version=${marketing_version}" \
|
||||
"upload=${upload} update_appcast=${update_appcast}" \
|
||||
"vimr_artifact_path=${vimr_artifact_path}"
|
||||
echo "create_gh_release=${create_gh_release} \\"
|
||||
echo "upload=${upload} update_appcast=${update_appcast} \\"
|
||||
echo "vimr_artifact_path=${vimr_artifact_path}"
|
||||
|
||||
pushd "$(dirname "${BASH_SOURCE[0]}")/.." >/dev/null
|
||||
|
||||
check_version
|
||||
check_upload
|
||||
prepare_bin
|
||||
build_release
|
||||
|
||||
if [[ "${create_gh_release}" == true ]]; then
|
||||
create_gh_release
|
||||
fi
|
||||
|
||||
if [[ "${upload}" == true ]]; then
|
||||
# Give GitHub some time.
|
||||
sleep 5
|
||||
check_gh_release_present
|
||||
upload_artifact
|
||||
fi
|
||||
|
||||
@ -106,6 +136,7 @@ main() {
|
||||
sleep 5
|
||||
update_appcast_file
|
||||
fi
|
||||
|
||||
popd >/dev/null
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@ main() {
|
||||
if [[ "${is_snapshot}" == true ]]; then
|
||||
marketing_version="SNAPSHOT-${bundle_version}"
|
||||
fi
|
||||
readonly marketing_version
|
||||
|
||||
pushd VimR >/dev/null
|
||||
agvtool new-version -all "${bundle_version}"
|
||||
@ -37,12 +36,45 @@ main() {
|
||||
echo "### Set versions of VimR"
|
||||
|
||||
local tag
|
||||
local github_release_name
|
||||
local version_marker
|
||||
if [[ "${is_snapshot}" == true ]]; then
|
||||
tag="snapshot/${bundle_version}"
|
||||
github_release_name="${marketing_version}"
|
||||
version_marker="snapshot"
|
||||
else
|
||||
tag="v${marketing_version}-${bundle_version}"
|
||||
github_release_name="$tag"
|
||||
version_marker="release"
|
||||
marketing_version="v${marketing_version}"
|
||||
fi
|
||||
echo "bundle_version=${bundle_version} marketing_version=v${marketing_version} tag=${tag}"
|
||||
readonly tag
|
||||
readonly github_release_name
|
||||
readonly version_marker
|
||||
readonly marketing_version
|
||||
|
||||
local output
|
||||
output=$(cat <<-END
|
||||
declare -r -x is_snapshot=${is_snapshot}
|
||||
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
|
||||
)
|
||||
END
|
||||
)
|
||||
readonly output
|
||||
|
||||
echo "${output}" > "${bundle_version}-${version_marker}.sh"
|
||||
|
||||
echo "### Tag, commit and push with ${tag}"
|
||||
echo "### Use the following to build a release:"
|
||||
echo "release_spec_file=${bundle_version}-${version_marker}.sh \\"
|
||||
echo "create_gh_release=true upload=true update_appcast=true \\"
|
||||
echo "./bin/build_release.sh"
|
||||
}
|
||||
|
||||
main
|
||||
|
@ -5,6 +5,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"vimrDeps": "vimr-deps-2021-12-12",
|
||||
"nvimServer": "nvimserver-0.6.1-1"
|
||||
"nvimServer": "nvimserver-0.7.0-0"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
# Next
|
||||
# 0.39.0-20220416.182927
|
||||
|
||||
* ...
|
||||
* Neovim 0.7.0 😀
|
||||
* GH-922: Add an option to set font smoothing.
|
||||
* GH-928: Bugfix: Files containing some special characters in their names cannot be opened.
|
||||
|
||||
# 0.38.2-20220322.180037
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user