1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-11-24 11:37:32 +03:00

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

This commit is contained in:
Tae Won Ha 2018-07-15 22:10:37 +02:00
commit 07f50b6b08
21 changed files with 303 additions and 363 deletions

View File

@ -10,5 +10,6 @@ github "qvacua/RxNeovimApi" "develop"
github "sindresorhus/github-markdown-css" == 2.10.0 github "sindresorhus/github-markdown-css" == 2.10.0
github "httpswift/swifter" == 1.4.2 github "httpswift/swifter" == 1.4.2
github "a2/MessagePack.swift" == 3.0.0 github "a2/MessagePack.swift" == 3.0.0
github "elegantchaos/DictionaryCoding" == 1.0.3
github "Quick/Nimble" == 7.1.2 github "Quick/Nimble" == 7.1.2

View File

@ -2,6 +2,7 @@ github "PureLayout/PureLayout" "v3.0.2"
github "Quick/Nimble" "v7.1.2" github "Quick/Nimble" "v7.1.2"
github "ReactiveX/RxSwift" "4.2.0" github "ReactiveX/RxSwift" "4.2.0"
github "a2/MessagePack.swift" "3.0.0" github "a2/MessagePack.swift" "3.0.0"
github "elegantchaos/DictionaryCoding" "1.0.3"
github "eonil/FileSystemEvents" "1.0.0" github "eonil/FileSystemEvents" "1.0.0"
github "httpswift/swifter" "1.4.2" github "httpswift/swifter" "1.4.2"
github "qvacua/CocoaFontAwesome" "76cf6c4ef3088d84f78988183c56fc6abdc19f83" github "qvacua/CocoaFontAwesome" "76cf6c4ef3088d84f78988183c56fc6abdc19f83"

View File

@ -470,7 +470,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 284; CURRENT_PROJECT_VERSION = 285;
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES; ENABLE_TESTABILITY = YES;
@ -530,7 +530,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 284; CURRENT_PROJECT_VERSION = 285;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
@ -557,7 +557,7 @@
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 284; DYLIB_CURRENT_VERSION = 285;
DYLIB_INSTALL_NAME_BASE = "@rpath"; DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../Carthage/Build/Mac"; FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../Carthage/Build/Mac";
FRAMEWORK_VERSION = A; FRAMEWORK_VERSION = A;
@ -579,7 +579,7 @@
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 284; DYLIB_CURRENT_VERSION = 285;
DYLIB_INSTALL_NAME_BASE = "@rpath"; DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../Carthage/Build/Mac"; FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../Carthage/Build/Mac";
FRAMEWORK_VERSION = A; FRAMEWORK_VERSION = A;

View File

@ -15,9 +15,9 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>SNAPSHOT-284</string> <string>SNAPSHOT-285</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>284</string> <string>285</string>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>Copyright © 2017 Tae Won Ha. All rights reserved.</string> <string>Copyright © 2017 Tae Won Ha. All rights reserved.</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>

View File

@ -142,7 +142,7 @@ extension NvimView {
case .insert: case .insert:
return self.bridge return self.bridge
.vimInput("<ESC>\"+pa") .vimInput("<ESC>\"+Pa")
.andThen(Single.just(pasteModeSet)) .andThen(Single.just(pasteModeSet))
case .normal, .visual: case .normal, .visual:

View File

@ -7,13 +7,11 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1929B00BA624DA8DC75F7E02 /* SerializableStates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BA42AB6F1BF631B57399 /* SerializableStates.swift */; };
1929B04CE8ECBD75CBBB0991 /* StringCommonsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B5D45C9792BBE76B8AFF /* StringCommonsTest.swift */; }; 1929B04CE8ECBD75CBBB0991 /* StringCommonsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B5D45C9792BBE76B8AFF /* StringCommonsTest.swift */; };
1929B05B9D664052EC2D23EF /* FileOutlineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BCE3E156C06EDF1F2806 /* FileOutlineView.swift */; }; 1929B05B9D664052EC2D23EF /* FileOutlineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BCE3E156C06EDF1F2806 /* FileOutlineView.swift */; };
1929B08C6230B9C5AB72DAF1 /* Pref128ToCurrentConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B5046239709E33516F5C /* Pref128ToCurrentConverter.swift */; }; 1929B08C6230B9C5AB72DAF1 /* Pref128ToCurrentConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B5046239709E33516F5C /* Pref128ToCurrentConverter.swift */; };
1929B0E0C3BC59F52713D5A2 /* FoundationCommons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B9AF20D7BD6E5C975128 /* FoundationCommons.swift */; }; 1929B0E0C3BC59F52713D5A2 /* FoundationCommons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B9AF20D7BD6E5C975128 /* FoundationCommons.swift */; };
1929B0F599D1F62C7BE53D2C /* HttpServerMiddleware.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B1DC584C89C477E83FA2 /* HttpServerMiddleware.swift */; }; 1929B0F599D1F62C7BE53D2C /* HttpServerMiddleware.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B1DC584C89C477E83FA2 /* HttpServerMiddleware.swift */; };
1929B10EE7FE8DC251B741B2 /* RxRedux.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B66A5E2D00EA143AFD86 /* RxRedux.swift */; };
1929B1837C750CADB3A5BCB9 /* OpenQuicklyFileViewRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B1558455B3A74D93EF2A /* OpenQuicklyFileViewRow.swift */; }; 1929B1837C750CADB3A5BCB9 /* OpenQuicklyFileViewRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B1558455B3A74D93EF2A /* OpenQuicklyFileViewRow.swift */; };
1929B20CE35B43BB1CE023BA /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BC2F05E9A5C0DB039739 /* Theme.swift */; }; 1929B20CE35B43BB1CE023BA /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BC2F05E9A5C0DB039739 /* Theme.swift */; };
1929B29B95AD176D57942E08 /* UiRootReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B457B9D0FA4D21F3751E /* UiRootReducer.swift */; }; 1929B29B95AD176D57942E08 /* UiRootReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B457B9D0FA4D21F3751E /* UiRootReducer.swift */; };
@ -81,6 +79,10 @@
1929BF4FF30D9A9DE82C3052 /* FileUtilsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B8042AC566CDF6C998A3 /* FileUtilsTest.swift */; }; 1929BF4FF30D9A9DE82C3052 /* FileUtilsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B8042AC566CDF6C998A3 /* FileUtilsTest.swift */; };
1929BFC70581084B5CE04A5B /* MatcherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BFE179BCA3C75A13D71B /* MatcherTests.swift */; }; 1929BFC70581084B5CE04A5B /* MatcherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BFE179BCA3C75A13D71B /* MatcherTests.swift */; };
1929BFDE22D155F7C4B19E96 /* HtmlPreviewTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B85023B042C485409CE1 /* HtmlPreviewTool.swift */; }; 1929BFDE22D155F7C4B19E96 /* HtmlPreviewTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B85023B042C485409CE1 /* HtmlPreviewTool.swift */; };
4B004BAA20FBA6700043A396 /* DictionaryCoding.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B004BA920FBA6700043A396 /* DictionaryCoding.framework */; };
4B004BAB20FBA6700043A396 /* DictionaryCoding.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4B004BA920FBA6700043A396 /* DictionaryCoding.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
4B004BAC20FBB4F10043A396 /* DictionaryCoding.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B004BA920FBA6700043A396 /* DictionaryCoding.framework */; };
4B004BAD20FBBE1E0043A396 /* DictionaryCoding.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4B004BA920FBA6700043A396 /* DictionaryCoding.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
4B029F1A1D45E349004EE0D3 /* PrefWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B029F1C1D45E349004EE0D3 /* PrefWindow.xib */; }; 4B029F1A1D45E349004EE0D3 /* PrefWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B029F1C1D45E349004EE0D3 /* PrefWindow.xib */; };
4B17E54D209E3EA400265C1D /* RxNeovimApi.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4B17E54C209E3EA400265C1D /* RxNeovimApi.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 4B17E54D209E3EA400265C1D /* RxNeovimApi.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4B17E54C209E3EA400265C1D /* RxNeovimApi.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
4B17E54E209E3EFA00265C1D /* RxNeovimApi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B17E54C209E3EA400265C1D /* RxNeovimApi.framework */; }; 4B17E54E209E3EFA00265C1D /* RxNeovimApi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B17E54C209E3EA400265C1D /* RxNeovimApi.framework */; };
@ -234,6 +236,7 @@
files = ( files = (
4BB1F5D22097706700EC394A /* MessagePack.framework in Embed Frameworks */, 4BB1F5D22097706700EC394A /* MessagePack.framework in Embed Frameworks */,
4BB1F5CF2097704D00EC394A /* RxMsgpackRpc.framework in Embed Frameworks */, 4BB1F5CF2097704D00EC394A /* RxMsgpackRpc.framework in Embed Frameworks */,
4B004BAB20FBA6700043A396 /* DictionaryCoding.framework in Embed Frameworks */,
4BF18C411FD2E2C900DF95D1 /* CocoaFontAwesome.framework in Embed Frameworks */, 4BF18C411FD2E2C900DF95D1 /* CocoaFontAwesome.framework in Embed Frameworks */,
4BF18C421FD2E2C900DF95D1 /* CocoaMarkdown.framework in Embed Frameworks */, 4BF18C421FD2E2C900DF95D1 /* CocoaMarkdown.framework in Embed Frameworks */,
4BF18C431FD2E2C900DF95D1 /* EonilFileSystemEvents.framework in Embed Frameworks */, 4BF18C431FD2E2C900DF95D1 /* EonilFileSystemEvents.framework in Embed Frameworks */,
@ -255,6 +258,7 @@
dstPath = ""; dstPath = "";
dstSubfolderSpec = 10; dstSubfolderSpec = 10;
files = ( files = (
4B004BAD20FBBE1E0043A396 /* DictionaryCoding.framework in CopyFiles */,
4B9DF28A209C8DBB00DF2AAD /* RxMessagePort.framework in CopyFiles */, 4B9DF28A209C8DBB00DF2AAD /* RxMessagePort.framework in CopyFiles */,
4B9DF289209C8DAD00DF2AAD /* RxMsgpackRpc.framework in CopyFiles */, 4B9DF289209C8DAD00DF2AAD /* RxMsgpackRpc.framework in CopyFiles */,
4B17E54F209E3EFD00265C1D /* RxNeovimApi.framework in CopyFiles */, 4B17E54F209E3EFD00265C1D /* RxNeovimApi.framework in CopyFiles */,
@ -313,7 +317,6 @@
1929B9355C892BEBA7496C71 /* DictionaryCommonsTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryCommonsTest.swift; sourceTree = "<group>"; }; 1929B9355C892BEBA7496C71 /* DictionaryCommonsTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryCommonsTest.swift; sourceTree = "<group>"; };
1929B9AF20D7BD6E5C975128 /* FoundationCommons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoundationCommons.swift; sourceTree = "<group>"; }; 1929B9AF20D7BD6E5C975128 /* FoundationCommons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoundationCommons.swift; sourceTree = "<group>"; };
1929B9D510177918080BE39B /* Scorer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Scorer.swift; sourceTree = "<group>"; }; 1929B9D510177918080BE39B /* Scorer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Scorer.swift; sourceTree = "<group>"; };
1929BA42AB6F1BF631B57399 /* SerializableStates.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SerializableStates.swift; sourceTree = "<group>"; };
1929BA43449BA41666CD55ED /* BufferList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BufferList.swift; sourceTree = "<group>"; }; 1929BA43449BA41666CD55ED /* BufferList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BufferList.swift; sourceTree = "<group>"; };
1929BA5C7099CDEB04B76BA4 /* FileBrowser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileBrowser.swift; sourceTree = "<group>"; }; 1929BA5C7099CDEB04B76BA4 /* FileBrowser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileBrowser.swift; sourceTree = "<group>"; };
1929BA8AC40B901B20F20B71 /* FileUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileUtils.swift; sourceTree = "<group>"; }; 1929BA8AC40B901B20F20B71 /* FileUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileUtils.swift; sourceTree = "<group>"; };
@ -342,6 +345,7 @@
1929BFB0F294F3714D5E095F /* PreviewToolReducer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreviewToolReducer.swift; sourceTree = "<group>"; }; 1929BFB0F294F3714D5E095F /* PreviewToolReducer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreviewToolReducer.swift; sourceTree = "<group>"; };
1929BFC0A5A9C6DB09BE1368 /* Types.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Types.swift; sourceTree = "<group>"; }; 1929BFC0A5A9C6DB09BE1368 /* Types.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Types.swift; sourceTree = "<group>"; };
1929BFE179BCA3C75A13D71B /* MatcherTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MatcherTests.swift; sourceTree = "<group>"; }; 1929BFE179BCA3C75A13D71B /* MatcherTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MatcherTests.swift; sourceTree = "<group>"; };
4B004BA920FBA6700043A396 /* DictionaryCoding.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DictionaryCoding.framework; path = ../Carthage/Build/Mac/DictionaryCoding.framework; sourceTree = "<group>"; };
4B029F1B1D45E349004EE0D3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/PrefWindow.xib; sourceTree = "<group>"; }; 4B029F1B1D45E349004EE0D3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/PrefWindow.xib; sourceTree = "<group>"; };
4B17E54C209E3EA400265C1D /* RxNeovimApi.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxNeovimApi.framework; path = ../Carthage/Build/Mac/RxNeovimApi.framework; sourceTree = "<group>"; }; 4B17E54C209E3EA400265C1D /* RxNeovimApi.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxNeovimApi.framework; path = ../Carthage/Build/Mac/RxNeovimApi.framework; sourceTree = "<group>"; };
4B19BEFA1E110183007E823C /* markdown */ = {isa = PBXFileReference; lastKnownFileType = folder; path = markdown; sourceTree = "<group>"; }; 4B19BEFA1E110183007E823C /* markdown */ = {isa = PBXFileReference; lastKnownFileType = folder; path = markdown; sourceTree = "<group>"; };
@ -455,6 +459,7 @@
files = ( files = (
4BB1F5D12097705E00EC394A /* MessagePack.framework in Frameworks */, 4BB1F5D12097705E00EC394A /* MessagePack.framework in Frameworks */,
4BB1F5CD20976F8900EC394A /* RxMsgpackRpc.framework in Frameworks */, 4BB1F5CD20976F8900EC394A /* RxMsgpackRpc.framework in Frameworks */,
4B004BAA20FBA6700043A396 /* DictionaryCoding.framework in Frameworks */,
4BF18C391FD2E2AB00DF95D1 /* EonilFileSystemEvents.framework in Frameworks */, 4BF18C391FD2E2AB00DF95D1 /* EonilFileSystemEvents.framework in Frameworks */,
4BF18C3A1FD2E2AB00DF95D1 /* PureLayout.framework in Frameworks */, 4BF18C3A1FD2E2AB00DF95D1 /* PureLayout.framework in Frameworks */,
4BF18C3B1FD2E2AB00DF95D1 /* CocoaMarkdown.framework in Frameworks */, 4BF18C3B1FD2E2AB00DF95D1 /* CocoaMarkdown.framework in Frameworks */,
@ -474,6 +479,7 @@
files = ( files = (
4BF18C581FD2E53400DF95D1 /* CocoaMarkdown.framework in Frameworks */, 4BF18C581FD2E53400DF95D1 /* CocoaMarkdown.framework in Frameworks */,
4BF18C511FD2E4F200DF95D1 /* RxTest.framework in Frameworks */, 4BF18C511FD2E4F200DF95D1 /* RxTest.framework in Frameworks */,
4B004BAC20FBB4F10043A396 /* DictionaryCoding.framework in Frameworks */,
4BF18C4F1FD2E4F100DF95D1 /* RxSwift.framework in Frameworks */, 4BF18C4F1FD2E4F100DF95D1 /* RxSwift.framework in Frameworks */,
4B17E54E209E3EFA00265C1D /* RxNeovimApi.framework in Frameworks */, 4B17E54E209E3EFA00265C1D /* RxNeovimApi.framework in Frameworks */,
4BF18C4C1FD2E4CE00DF95D1 /* NvimView.framework in Frameworks */, 4BF18C4C1FD2E4CE00DF95D1 /* NvimView.framework in Frameworks */,
@ -570,7 +576,6 @@
1929B5E773BDB3B4EE9D00C1 /* Reducers */, 1929B5E773BDB3B4EE9D00C1 /* Reducers */,
1929BFA93DC859DD76C46192 /* Middlewares */, 1929BFA93DC859DD76C46192 /* Middlewares */,
1929BFC0A5A9C6DB09BE1368 /* Types.swift */, 1929BFC0A5A9C6DB09BE1368 /* Types.swift */,
1929BA42AB6F1BF631B57399 /* SerializableStates.swift */,
); );
name = UI; name = UI;
sourceTree = "<group>"; sourceTree = "<group>";
@ -637,6 +642,7 @@
4B5012001EBA791000F76C46 /* Frameworks */ = { 4B5012001EBA791000F76C46 /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4B004BA920FBA6700043A396 /* DictionaryCoding.framework */,
4B17E54C209E3EA400265C1D /* RxNeovimApi.framework */, 4B17E54C209E3EA400265C1D /* RxNeovimApi.framework */,
4B9E5E1D20990E08006455C3 /* RxMessagePort.framework */, 4B9E5E1D20990E08006455C3 /* RxMessagePort.framework */,
4BB1F5D02097705E00EC394A /* MessagePack.framework */, 4BB1F5D02097705E00EC394A /* MessagePack.framework */,
@ -1083,7 +1089,6 @@
1929B4F0612224E594E89B92 /* AppearancePref.swift in Sources */, 1929B4F0612224E594E89B92 /* AppearancePref.swift in Sources */,
1929B50D933A369A86A165DE /* AdvencedPref.swift in Sources */, 1929B50D933A369A86A165DE /* AdvencedPref.swift in Sources */,
1929BCC7908DD899999B70BE /* AppearancePrefReducer.swift in Sources */, 1929BCC7908DD899999B70BE /* AppearancePrefReducer.swift in Sources */,
1929B00BA624DA8DC75F7E02 /* SerializableStates.swift in Sources */,
1929B3557317755A43513B17 /* OpenQuicklyWindow.swift in Sources */, 1929B3557317755A43513B17 /* OpenQuicklyWindow.swift in Sources */,
1929B333855A5406C400DA92 /* OpenQuicklyFilterOperation.swift in Sources */, 1929B333855A5406C400DA92 /* OpenQuicklyFilterOperation.swift in Sources */,
1929B1837C750CADB3A5BCB9 /* OpenQuicklyFileViewRow.swift in Sources */, 1929B1837C750CADB3A5BCB9 /* OpenQuicklyFileViewRow.swift in Sources */,
@ -1135,7 +1140,6 @@
1929B8E90A1378E494D481E7 /* PrefUtilsTest.swift in Sources */, 1929B8E90A1378E494D481E7 /* PrefUtilsTest.swift in Sources */,
1929B20CE35B43BB1CE023BA /* Theme.swift in Sources */, 1929B20CE35B43BB1CE023BA /* Theme.swift in Sources */,
1929B9318D32146D58BB38EC /* AppKitCommons.swift in Sources */, 1929B9318D32146D58BB38EC /* AppKitCommons.swift in Sources */,
1929B10EE7FE8DC251B741B2 /* RxRedux.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -1230,7 +1234,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 284; CURRENT_PROJECT_VERSION = 285;
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES; ENABLE_TESTABILITY = YES;
@ -1287,7 +1291,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 284; CURRENT_PROJECT_VERSION = 285;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;

View File

@ -8,6 +8,7 @@ import RxSwift
import PureLayout import PureLayout
import Sparkle import Sparkle
import CocoaFontAwesome import CocoaFontAwesome
import DictionaryCoding
@NSApplicationMain @NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDelegate { class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDelegate {
@ -35,8 +36,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
let baseServerUrl = URL(string: "http://localhost:\(NetUtils.openPort())")! let baseServerUrl = URL(string: "http://localhost:\(NetUtils.openPort())")!
var initialAppState: AppState var initialAppState: AppState
if let stateDict = UserDefaults.standard.value(forKey: PrefMiddleware.compatibleVersion) as? [String: Any] {
initialAppState = AppState(dict: stateDict) ?? .default let dictDecoder = DictionaryDecoder()
if let stateDict = UserDefaults.standard.value(forKey: PrefMiddleware.compatibleVersion) as? [String: Any],
let state = try? dictDecoder.decode(AppState.self, from: stateDict) {
initialAppState = state
} else { } else {
if let oldDict = UserDefaults.standard.value(forKey: PrefMiddleware.lastCompatibleVersion) as? [String: Any] { if let oldDict = UserDefaults.standard.value(forKey: PrefMiddleware.lastCompatibleVersion) as? [String: Any] {
initialAppState = Pref128ToCurrentConverter.appState(from: oldDict) initialAppState = Pref128ToCurrentConverter.appState(from: oldDict)
@ -44,6 +49,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
initialAppState = .default initialAppState = .default
} }
} }
initialAppState.mainWindowTemplate.htmlPreview.server = Marked( initialAppState.mainWindowTemplate.htmlPreview.server = Marked(
baseServerUrl.appendingPathComponent(HtmlPreviewToolReducer.selectFirstPath) baseServerUrl.appendingPathComponent(HtmlPreviewToolReducer.selectFirstPath)
) )

View File

@ -1,4 +1,4 @@
{\rtf1\ansi\ansicpg1252\cocoartf1561\cocoasubrtf400 {\rtf1\ansi\ansicpg1252\cocoartf1561\cocoasubrtf600
{\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;} {\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;} {\*\expandedcolortbl;;}
@ -99,6 +99,11 @@ By:
\b0 \ \b0 \
\ \
\b DictionaryCoding
\b0 \
{\field{\*\fldinst{HYPERLINK "https://github.com/elegantchaos/DictionaryCoding"}}{\fldrslt https://github.com/elegantchaos/DictionaryCoding}}\
\
\b Nimble \b Nimble
\b0 \ \b0 \
{\field{\*\fldinst{HYPERLINK "https://github.com/Quick/Nimble"}}{\fldrslt https://github.com/Quick/Nimble}}\ {\field{\*\fldinst{HYPERLINK "https://github.com/Quick/Nimble"}}{\fldrslt https://github.com/Quick/Nimble}}\

View File

@ -86,7 +86,6 @@ class Context: ReduxContext {
httpMiddleware.mainWindow.apply, httpMiddleware.mainWindow.apply,
previewMiddleware.previewTool.apply, previewMiddleware.previewTool.apply,
httpMiddleware.htmlPreview.apply, httpMiddleware.htmlPreview.apply,
previewMiddleware.buffersList.apply,
] ]
) )
.filter { $0.modified } .filter { $0.modified }

View File

@ -49,7 +49,7 @@ class HttpServerMiddleware {
return { tuple in return { tuple in
let result = reduce(tuple) let result = reduce(tuple)
guard tuple.modified else { guard case .selectHtmlFile = tuple.action.payload else {
return result return result
} }
@ -58,6 +58,7 @@ class HttpServerMiddleware {
return result return result
} }
fileLog.debug("Serving \(htmlFileUrl) on \(serverUrl)")
let basePath = serverUrl.payload.deletingLastPathComponent().path let basePath = serverUrl.payload.deletingLastPathComponent().path
self.server.GET[serverUrl.payload.path] = shareFile(htmlFileUrl.path) self.server.GET[serverUrl.payload.path] = shareFile(htmlFileUrl.path)
@ -85,10 +86,6 @@ class HttpServerMiddleware {
return { tuple in return { tuple in
let result = reduce(tuple) let result = reduce(tuple)
guard tuple.modified else {
return result
}
let uuidAction = tuple.action let uuidAction = tuple.action
guard case .newCurrentBuffer = uuidAction.payload else { guard case .newCurrentBuffer = uuidAction.payload else {
return result return result
@ -104,7 +101,6 @@ class HttpServerMiddleware {
} }
fileLog.debug("Serving \(html) on \(server)") fileLog.debug("Serving \(html) on \(server)")
let htmlBasePath = server.deletingLastPathComponent().path let htmlBasePath = server.deletingLastPathComponent().path
self.server["\(htmlBasePath)/:path"] = shareFilesFromDirectory(buffer.deletingLastPathComponent().path) self.server["\(htmlBasePath)/:path"] = shareFilesFromDirectory(buffer.deletingLastPathComponent().path)

View File

@ -1224,7 +1224,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>SNAPSHOT-284</string> <string>SNAPSHOT-285</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleURLTypes</key> <key>CFBundleURLTypes</key>
@ -1241,7 +1241,7 @@
</dict> </dict>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>284</string> <string>285</string>
<key>LSApplicationCategoryType</key> <key>LSApplicationCategoryType</key>
<string>public.app-category.productivity</string> <string>public.app-category.productivity</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>

View File

@ -52,7 +52,7 @@ class MainWindow: NSObject,
case preview case preview
} }
enum Tools: String { enum Tools: String, Codable {
static let all = Set([Tools.fileBrowser, Tools.buffersList, Tools.preview, Tools.htmlPreview]) static let all = Set([Tools.fileBrowser, Tools.buffersList, Tools.preview, Tools.htmlPreview])

View File

@ -4,6 +4,7 @@
*/ */
import Foundation import Foundation
import DictionaryCoding
class PrefMiddleware: MiddlewareType { class PrefMiddleware: MiddlewareType {
@ -17,7 +18,12 @@ class PrefMiddleware: MiddlewareType {
// The following should only be used when Cmd-Q'ing // The following should only be used when Cmd-Q'ing
func applyPref(from appState: AppState) { func applyPref(from appState: AppState) {
defaults.setValue(appState.dict(), forKey: PrefMiddleware.compatibleVersion) do {
let dictionary: [String: Any] = try dictEncoder.encode(appState)
defaults.set(dictionary, forKey: PrefMiddleware.compatibleVersion)
} catch {
fileLog.error("AppState could not converted to Dictionary: \(error)")
}
} }
func typedApply(_ reduce: @escaping TypedActionReduceFunction) -> TypedActionReduceFunction { func typedApply(_ reduce: @escaping TypedActionReduceFunction) -> TypedActionReduceFunction {
@ -28,7 +34,12 @@ class PrefMiddleware: MiddlewareType {
return result return result
} }
defaults.setValue(result.state.dict(), forKey: PrefMiddleware.compatibleVersion) do {
let dictionary: [String: Any] = try dictEncoder.encode(result.state)
defaults.set(dictionary, forKey: PrefMiddleware.compatibleVersion)
} catch {
fileLog.error("AppState could not converted to Dictionary: \(error)")
}
return result return result
} }
@ -52,7 +63,13 @@ class PrefMiddleware: MiddlewareType {
return result return result
} }
defaults.setValue(result.state.dict(), forKey: PrefMiddleware.compatibleVersion) do {
let dictionary: [String: Any] = try dictEncoder.encode(result.state)
defaults.set(dictionary, forKey: PrefMiddleware.compatibleVersion)
} catch {
fileLog.error("AppState could not converted to Dictionary: \(error)")
}
return result return result
} }
} }
@ -60,3 +77,4 @@ class PrefMiddleware: MiddlewareType {
} }
private let defaults = UserDefaults.standard private let defaults = UserDefaults.standard
private let dictEncoder = DictionaryEncoder()

View File

@ -9,13 +9,11 @@ import CocoaMarkdown
class PreviewMiddleware { class PreviewMiddleware {
let previewTool: PreviewToolMiddleware let previewTool: PreviewToolMiddleware
let buffersList: BuffersListMiddleware
let mainWindow: MainWindowMiddleware let mainWindow: MainWindowMiddleware
init() { init() {
let generator = PreviewGenerator() let generator = PreviewGenerator()
self.previewTool = PreviewToolMiddleware(generator: generator) self.previewTool = PreviewToolMiddleware(generator: generator)
self.buffersList = BuffersListMiddleware(generator: generator)
self.mainWindow = MainWindowMiddleware(generator: generator) self.mainWindow = MainWindowMiddleware(generator: generator)
} }
@ -49,7 +47,7 @@ class PreviewMiddleware {
return return
} }
fileLog.debug("\(buffer) -> \(html)") stdoutLog.debug("\(buffer) -> \(html)")
do { do {
try self.render(buffer, to: html) try self.render(buffer, to: html)
self.previewFiles[uuid] = html self.previewFiles[uuid] = html
@ -98,10 +96,6 @@ class PreviewMiddleware {
return { tuple in return { tuple in
let result = reduce(tuple) let result = reduce(tuple)
guard tuple.modified else {
return result
}
let uuidAction = tuple.action let uuidAction = tuple.action
guard case .refreshNow = uuidAction.payload else { guard case .refreshNow = uuidAction.payload else {
return result return result
@ -115,37 +109,6 @@ class PreviewMiddleware {
private let generator: PreviewGenerator private let generator: PreviewGenerator
} }
class BuffersListMiddleware: MiddlewareType {
typealias StateType = MainWindow.State
typealias ActionType = UuidAction<BuffersList.Action>
init(generator: PreviewGenerator) {
self.generator = generator
}
func typedApply(_ reduce: @escaping TypedActionReduceFunction) -> TypedActionReduceFunction {
return { tuple in
let result = reduce(tuple)
guard tuple.modified else {
return result
}
let uuidAction = tuple.action
guard case .open = uuidAction.payload else {
return result
}
self.generator.apply(result.state, uuid: uuidAction.uuid)
return result
}
}
private let generator: PreviewGenerator
}
class MainWindowMiddleware: MiddlewareType { class MainWindowMiddleware: MiddlewareType {
typealias StateType = MainWindow.State typealias StateType = MainWindow.State
@ -159,10 +122,6 @@ class PreviewMiddleware {
return { tuple in return { tuple in
let result = reduce(tuple) let result = reduce(tuple)
guard tuple.modified else {
return result
}
let uuidAction = tuple.action let uuidAction = tuple.action
switch uuidAction.payload { switch uuidAction.payload {

View File

@ -6,7 +6,7 @@
import Cocoa import Cocoa
import RxSwift import RxSwift
extension Observable { extension ObservableType {
func mapOmittingNil<R>(_ transform: @escaping (E) throws -> R?) -> RxSwift.Observable<R> { func mapOmittingNil<R>(_ transform: @escaping (E) throws -> R?) -> RxSwift.Observable<R> {
return self return self

View File

@ -1,77 +0,0 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
import Foundation
protocol SerializableState {
init?(dict: [String: Any])
func dict() -> [String: Any]
}
class Keys {
static let openNewOnLaunch = "open-new-window-when-launching"
static let openNewOnReactivation = "open-new-window-on-reactivation"
static let afterLastWindowAction = "after-last-window-action"
static let useSnapshotUpdateChannel = "use-snapshot-update-channel"
class OpenQuickly {
static let key = "open-quickly"
static let ignorePatterns = "ignore-patterns"
}
class Appearance {
static let key = "appearance"
static let usesTheme = "uses-theme"
static let showsFileIcon = "shows-file-icon"
static let editorFontName = "editor-font-name"
static let editorFontSize = "editor-font-size"
static let editorLinespacing = "editor-linespacing"
static let editorUsesLigatures = "editor-uses-ligatures"
}
class MainWindow {
static let key = "main-window"
static let allToolsVisible = "is-all-tools-visible"
static let toolButtonsVisible = "is-tool-buttons-visible"
static let orderedTools = "ordered-tools"
static let activeTools = "active-tools"
static let frame = "frame"
static let isLeftOptionMeta = "is-left-option-meta"
static let isRightOptionMeta = "is-right-option-meta"
static let trackpadScrollResistance = "trackpad-scroll-resistance"
static let useInteractiveZsh = "use-interactive-zsh"
static let useLiveResize = "use-live-resize"
static let isShowHidden = "is-show-hidden"
}
class PreviewTool {
static let key = "preview-tool"
static let forwardSearchAutomatically = "is-forward-search-automatically"
static let reverseSearchAutomatically = "is-reverse-search-automatically"
static let refreshOnWrite = "is-refresh-on-write"
}
class WorkspaceTool {
static let key = "workspace-tool"
static let location = "location"
static let open = "is-visible"
static let dimension = "dimension"
}
}

View File

@ -6,9 +6,9 @@
import Foundation import Foundation
import RxSwift import RxSwift
struct AppState: SerializableState { struct AppState: Codable {
enum AfterLastWindowAction: String { enum AfterLastWindowAction: String, Codable {
case doNothing = "do-nothing" case doNothing = "do-nothing"
case hide = "hide" case hide = "hide"
@ -17,6 +17,17 @@ struct AppState: SerializableState {
static let `default` = AppState() static let `default` = AppState()
enum CodingKeys: String, CodingKey {
case openNewMainWindowOnLaunch = "open-new-window-when-launching"
case openNewMainWindowOnReactivation = "open-new-window-on-reactivation"
case afterLastWindowAction = "after-last-window-action"
case useSnapshotUpdate = "use-snapshot-update-channel"
case openQuickly = "open-quickly"
case mainWindowTemplate = "main-window"
}
var openNewMainWindowOnLaunch = true var openNewMainWindowOnLaunch = true
var openNewMainWindowOnReactivation = true var openNewMainWindowOnReactivation = true
@ -35,79 +46,64 @@ struct AppState: SerializableState {
var quit = false var quit = false
init() { init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.openNewMainWindowOnLaunch = try container.decode(forKey: .openNewMainWindowOnLaunch,
default: AppState.default.openNewMainWindowOnLaunch)
self.openNewMainWindowOnReactivation = try container.decode(
forKey: .openNewMainWindowOnReactivation, default: AppState.default.openNewMainWindowOnReactivation
)
self.afterLastWindowAction = try container.decode(forKey: .afterLastWindowAction, default: .doNothing)
self.useSnapshotUpdate = try container.decode(forKey: .useSnapshotUpdate,
default: AppState.default.useSnapshotUpdate)
self.openQuickly = try container.decode(forKey: .openQuickly, default: OpenQuicklyWindow.State.default)
self.mainWindowTemplate = try container.decode(forKey: .mainWindowTemplate, default: MainWindow.State.default)
} }
init?(dict: [String: Any]) { // Use generated encode(to:)
guard let openOnLaunch = PrefUtils.bool(from: dict, for: Keys.openNewOnLaunch),
let openOnReactivation = PrefUtils.bool(from: dict, for: Keys.openNewOnReactivation),
let useSnapshot = PrefUtils.bool(from: dict, for: Keys.useSnapshotUpdateChannel)
else {
return nil
}
self.openNewMainWindowOnLaunch = openOnLaunch private init() {
self.openNewMainWindowOnReactivation = openOnReactivation
let lastWindowActionString = PrefUtils.string(from: dict, for: Keys.afterLastWindowAction)
?? AfterLastWindowAction.doNothing.rawValue
self.afterLastWindowAction = AfterLastWindowAction(rawValue: lastWindowActionString) ?? .doNothing
self.useSnapshotUpdate = useSnapshot
let openQuicklyDict = dict[Keys.OpenQuickly.key] as? [String: Any] ?? [:]
self.openQuickly = OpenQuicklyWindow.State(dict: openQuicklyDict) ?? OpenQuicklyWindow.State.default
let mainWindowDict = dict[Keys.MainWindow.key] as? [String: Any] ?? [:]
self.mainWindowTemplate = MainWindow.State(dict: mainWindowDict) ?? MainWindow.State.default
}
func dict() -> [String: Any] {
return [
Keys.openNewOnLaunch: self.openNewMainWindowOnLaunch,
Keys.openNewOnReactivation: self.openNewMainWindowOnReactivation,
Keys.afterLastWindowAction: self.afterLastWindowAction.rawValue,
Keys.useSnapshotUpdateChannel: self.useSnapshotUpdate,
Keys.OpenQuickly.key: self.openQuickly.dict(),
Keys.MainWindow.key: self.mainWindowTemplate.dict(),
]
} }
} }
extension OpenQuicklyWindow { extension OpenQuicklyWindow {
struct State: SerializableState { struct State: Codable {
static let `default` = State() static let `default` = State()
static let defaultIgnorePatterns = Set(["*/.git", "*.o", "*.d", "*.dia"].map(FileItemIgnorePattern.init))
enum CodingKeys: String, CodingKey {
case ignorePatterns = "ignore-patterns"
}
let root = FileItem(URL(fileURLWithPath: "/", isDirectory: true)) let root = FileItem(URL(fileURLWithPath: "/", isDirectory: true))
var flatFileItems = Observable<[FileItem]>.empty() var flatFileItems = Observable<[FileItem]>.empty()
var cwd = FileUtils.userHomeUrl var cwd = FileUtils.userHomeUrl
var ignorePatterns = Set(["*/.git", "*.o", "*.d", "*.dia"].map(FileItemIgnorePattern.init)) var ignorePatterns = State.defaultIgnorePatterns
var ignoreToken = Token() var ignoreToken = Token()
var open = false var open = false
init() { init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
} if let patternsAsString = try container.decodeIfPresent(String.self, forKey: .ignorePatterns) {
self.ignorePatterns = FileItemIgnorePattern.from(string: patternsAsString)
init?(dict: [String: Any]) { } else {
guard let patternsString = PrefUtils.string(from: dict, for: Keys.OpenQuickly.ignorePatterns) else { self.ignorePatterns = State.defaultIgnorePatterns
return nil
} }
self.ignorePatterns = FileItemIgnorePattern.from(string: patternsString)
} }
func dict() -> [String: Any] { func encode(to encoder: Encoder) throws {
return [ var container = encoder.container(keyedBy: CodingKeys.self)
Keys.OpenQuickly.ignorePatterns: FileItemIgnorePattern.toString(self.ignorePatterns) try container.encode(FileItemIgnorePattern.toString(self.ignorePatterns), forKey: .ignorePatterns)
] }
private init() {
} }
} }
} }
@ -170,10 +166,20 @@ struct HtmlPreviewState {
var server: Marked<URL>? var server: Marked<URL>?
} }
struct AppearanceState: SerializableState { struct AppearanceState: Codable {
static let `default` = AppearanceState() static let `default` = AppearanceState()
enum CodingKeys: String, CodingKey {
case usesTheme = "uses-theme"
case showsFileIcon = "shows-file-icon"
case editorFontName = "editor-font-name"
case editorFontSize = "editor-font-size"
case editorLinespacing = "editor-linespacing"
case editorUsesLigatures = "editor-uses-ligatures"
}
var font = NSFont.userFixedPitchFont(ofSize: 13)! var font = NSFont.userFixedPitchFont(ofSize: 13)!
var linespacing: CGFloat = 1 var linespacing: CGFloat = 1
var usesLigatures = false var usesLigatures = false
@ -182,45 +188,54 @@ struct AppearanceState: SerializableState {
var showsFileIcon = true var showsFileIcon = true
var theme = Marked(Theme.default) var theme = Marked(Theme.default)
init() { init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
} if let fontName = try container.decodeIfPresent(String.self, forKey: .editorFontName),
let fontSize = try container.decodeIfPresent(Float.self, forKey: .editorFontSize),
init?(dict: [String: Any]) { let font = NSFont(name: fontName, size: CGFloat(fontSize)) {
guard let editorFontName = dict[Keys.Appearance.editorFontName] as? String, self.font = font
let fEditorFontSize = PrefUtils.float(from: dict, for: Keys.Appearance.editorFontSize), } else {
let fEditorLinespacing = PrefUtils.float(from: dict, for: Keys.Appearance.editorLinespacing), self.font = NvimView.defaultFont
let editorUsesLigatures = PrefUtils.bool(from: dict, for: Keys.Appearance.editorUsesLigatures)
else {
return nil
} }
self.usesTheme = PrefUtils.bool(from: dict, for: Keys.Appearance.usesTheme, default: true) self.linespacing = CGFloat(try container.decodeIfPresent(Float.self, forKey: .editorLinespacing) ?? 1.0)
self.showsFileIcon = PrefUtils.bool(from: dict, for: Keys.Appearance.showsFileIcon, default: true) self.usesLigatures = try container.decodeIfPresent(Bool.self, forKey: .editorUsesLigatures) ?? true
self.font = PrefUtils.saneFont(editorFontName, fontSize: CGFloat(fEditorFontSize)) self.usesTheme = try container.decodeIfPresent(Bool.self, forKey: .usesTheme) ?? true
self.linespacing = CGFloat(fEditorLinespacing) self.showsFileIcon = try container.decodeIfPresent(Bool.self, forKey: .showsFileIcon) ?? true
self.usesLigatures = editorUsesLigatures
} }
func dict() -> [String: Any] { func encode(to encoder: Encoder) throws {
return [ var container = encoder.container(keyedBy: CodingKeys.self)
Keys.Appearance.usesTheme: self.usesTheme,
Keys.Appearance.showsFileIcon: self.showsFileIcon, try container.encode(self.usesTheme, forKey: .usesTheme)
Keys.Appearance.editorFontName: self.font.fontName, try container.encode(self.showsFileIcon, forKey: .showsFileIcon)
Keys.Appearance.editorFontSize: Float(self.font.pointSize), try container.encode(self.font.fontName, forKey: .editorFontName)
Keys.Appearance.editorLinespacing: Float(self.linespacing), try container.encode(self.font.pointSize, forKey: .editorFontSize)
Keys.Appearance.editorUsesLigatures: self.usesLigatures, try container.encode(self.linespacing, forKey: .editorLinespacing)
] try container.encode(self.usesLigatures, forKey: .editorUsesLigatures)
}
private init() {
} }
} }
extension MainWindow { extension MainWindow {
struct State: SerializableState { struct State: Codable {
static let `default` = State(isAllToolsVisible: true, isToolButtonsVisible: true) static let `default` = State(isAllToolsVisible: true, isToolButtonsVisible: true)
static let defaultTools: [MainWindow.Tools: WorkspaceToolState] = [
.fileBrowser: WorkspaceToolState(location: .left, dimension: 200, open: true),
.buffersList: WorkspaceToolState(location: .left, dimension: 200, open: false),
.preview: WorkspaceToolState(location: .right, dimension: 250, open: false),
.htmlPreview: WorkspaceToolState(location: .right, dimension: 500, open: false),
]
static let orderedDefault: [MainWindow.Tools] = [.fileBrowser, .buffersList, .preview, .htmlPreview]
var isAllToolsVisible = true var isAllToolsVisible = true
var isToolButtonsVisible = true var isToolButtonsVisible = true
var activeTools = [ var activeTools = [
@ -236,8 +251,8 @@ extension MainWindow {
var goToLineFromCli: Marked<Int>? var goToLineFromCli: Marked<Int>?
var lastFileSystemUpdate = Marked(FileUtils.userHomeUrl) var lastFileSystemUpdate = Marked(FileUtils.userHomeUrl)
var tools = WorkspaceToolState.default var tools = MainWindow.State.defaultTools
var orderedTools = WorkspaceToolState.orderedDefault var orderedTools = MainWindow.State.orderedDefault
var preview = PreviewState.default var preview = PreviewState.default
var htmlPreview = HtmlPreviewState.default var htmlPreview = HtmlPreviewState.default
@ -277,42 +292,57 @@ extension MainWindow {
self.isToolButtonsVisible = isToolButtonsVisible self.isToolButtonsVisible = isToolButtonsVisible
} }
init?(dict: [String: Any]) { enum CodingKeys: String, CodingKey {
guard let isAllToolsVisible = PrefUtils.bool(from: dict, for: Keys.MainWindow.allToolsVisible),
let isToolButtonsVisible = PrefUtils.bool(from: dict, for: Keys.MainWindow.toolButtonsVisible), case allToolsVisible = "is-all-tools-visible"
let orderedToolsAsString = dict[Keys.MainWindow.orderedTools] as? [String], case toolButtonsVisible = "is-tool-buttons-visible"
let isShowHidden = PrefUtils.bool(from: dict, for: Keys.MainWindow.isShowHidden) case orderedTools = "ordered-tools"
else { case activeTools = "active-tools"
return nil case frame = "frame"
case isLeftOptionMeta = "is-left-option-meta"
case isRightOptionMeta = "is-right-option-meta"
case trackpadScrollResistance = "trackpad-scroll-resistance"
case useInteractiveZsh = "use-interactive-zsh"
case useLiveResize = "use-live-resize"
case isShowHidden = "is-show-hidden"
case appearance = "appearance"
case workspaceTools = "workspace-tool"
case previewTool = "preview-tool"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.isLeftOptionMeta = try container.decode(forKey: .isLeftOptionMeta, default: State.default.isLeftOptionMeta)
self.isRightOptionMeta = try container.decode(forKey: .isRightOptionMeta,
default: State.default.isRightOptionMeta)
self.useInteractiveZsh = try container.decode(forKey: .useInteractiveZsh,
default: State.default.useInteractiveZsh)
self.trackpadScrollResistance = try container.decode(forKey: .trackpadScrollResistance,
default: State.default.trackpadScrollResistance)
self.useLiveResize = try container.decode(forKey: .useLiveResize, default: State.default.useLiveResize)
if let frameRawValue = try container.decodeIfPresent(String.self, forKey: .frame) {
self.frame = NSRectFromString(frameRawValue)
} else {
self.frame = CGRect(x: 100, y: 100, width: 600, height: 400)
} }
// Stay compatible with 168 self.isAllToolsVisible = try container.decode(forKey: .allToolsVisible, default: State.default.isAllToolsVisible)
self.isLeftOptionMeta = PrefUtils.bool(from: dict, for: Keys.MainWindow.isLeftOptionMeta, default: false) self.isToolButtonsVisible = try container.decode(forKey: .toolButtonsVisible,
self.isRightOptionMeta = PrefUtils.bool(from: dict, for: Keys.MainWindow.isRightOptionMeta, default: false) default: State.default.isToolButtonsVisible)
self.useInteractiveZsh = PrefUtils.bool(from: dict, for: Keys.MainWindow.useInteractiveZsh, default: false) self.appearance = try container.decode(forKey: .appearance, default: State.default.appearance)
self.trackpadScrollResistance = PrefUtils.value(from: dict,
for: Keys.MainWindow.trackpadScrollResistance,
default: 5.0)
self.useLiveResize = PrefUtils.bool(from: dict, for: Keys.MainWindow.useLiveResize, default: false)
let frameString = PrefUtils.string(from: dict,
for: Keys.MainWindow.frame,
default: NSStringFromRect(self.frame))
self.frame = NSRectFromString(frameString)
self.isAllToolsVisible = isAllToolsVisible self.orderedTools = try container.decode(forKey: .orderedTools, default: State.default.orderedTools)
self.isToolButtonsVisible = isToolButtonsVisible
let appearanceDict = dict[Keys.Appearance.key] as? [String: Any] ?? [:]
self.appearance = AppearanceState(dict: appearanceDict) ?? AppearanceState.default
self.orderedTools = orderedToolsAsString.compactMap { MainWindow.Tools(rawValue: $0) }
let missingOrderedTools = MainWindow.Tools.all.subtracting(self.orderedTools) let missingOrderedTools = MainWindow.Tools.all.subtracting(self.orderedTools)
self.orderedTools.append(contentsOf: missingOrderedTools) self.orderedTools.append(contentsOf: missingOrderedTools)
// To stay compatible with 168 we do not guard against nil activeToolsAsString. // See [1]
let activeToolsAsString = dict[Keys.MainWindow.activeTools] as? [String: Bool] ?? [:] let rawActiveTools: [String: Bool] = try container.decode(forKey: .activeTools, default: [:])
self.activeTools = activeToolsAsString.flatMapToDict { (key, value) in self.activeTools = rawActiveTools.flatMapToDict { (key, value) in
guard let toolId = MainWindow.Tools(rawValue: key) else { guard let toolId = MainWindow.Tools(rawValue: key) else {
return nil return nil
} }
@ -322,138 +352,135 @@ extension MainWindow {
let missingActiveTools = MainWindow.Tools.all.subtracting(self.activeTools.keys) let missingActiveTools = MainWindow.Tools.all.subtracting(self.activeTools.keys)
missingActiveTools.forEach { self.activeTools[$0] = true } missingActiveTools.forEach { self.activeTools[$0] = true }
let workspaceToolsDict = dict[Keys.WorkspaceTool.key] as? [String: [String: Any]] ?? [:] let rawTools: [String: WorkspaceToolState] = try container.decode(forKey: .workspaceTools, default: [:])
let toolKeys = workspaceToolsDict.keys.compactMap { MainWindow.Tools(rawValue: $0) } self.tools = rawTools.flatMapToDict { (key, value) in
let missingToolKeys = MainWindow.Tools.all.subtracting(toolKeys) guard let tool = MainWindow.Tools(rawValue: key) else {
return nil
}
var tools = Array(toolKeys).toDict { tool in return (tool, value)
return WorkspaceToolState(dict: workspaceToolsDict[tool.rawValue]!) ?? WorkspaceToolState.default[tool]!
} }
missingToolKeys.forEach { missingTool in let missingTools = MainWindow.Tools.all.subtracting(self.tools.keys)
tools[missingTool] = WorkspaceToolState.default[missingTool]! missingTools.forEach { missingTool in
self.tools[missingTool] = MainWindow.State.defaultTools[missingTool]!
} }
self.tools = tools self.previewTool = try container.decode(forKey: .previewTool, default: State.default.previewTool)
self.fileBrowserShowHidden = try container.decode(forKey: .isShowHidden,
let previewToolDict = dict[Keys.PreviewTool.key] as? [String: Any] ?? [:] default: State.default.fileBrowserShowHidden)
self.previewTool = PreviewTool.State(dict: previewToolDict) ?? PreviewTool.State.default
self.fileBrowserShowHidden = isShowHidden
} }
func dict() -> [String: Any] { func encode(to encoder: Encoder) throws {
return [ var container = encoder.container(keyedBy: CodingKeys.self)
Keys.MainWindow.allToolsVisible: self.isAllToolsVisible,
Keys.MainWindow.toolButtonsVisible: self.isToolButtonsVisible,
Keys.MainWindow.frame: NSStringFromRect(self.frame), try container.encode(self.isAllToolsVisible, forKey: .allToolsVisible)
try container.encode(self.isToolButtonsVisible, forKey: .toolButtonsVisible)
try container.encode(NSStringFromRect(self.frame), forKey: .frame)
try container.encode(self.trackpadScrollResistance, forKey: .trackpadScrollResistance)
try container.encode(self.useLiveResize, forKey: .useLiveResize)
try container.encode(self.isLeftOptionMeta, forKey: .isLeftOptionMeta)
try container.encode(self.isRightOptionMeta, forKey: .isRightOptionMeta)
try container.encode(self.useInteractiveZsh, forKey: .useInteractiveZsh)
try container.encode(self.fileBrowserShowHidden, forKey: .isShowHidden)
Keys.MainWindow.trackpadScrollResistance: self.trackpadScrollResistance, // See [1]
Keys.MainWindow.useLiveResize: self.useLiveResize, try container.encode(Dictionary(uniqueKeysWithValues: self.tools.map { k, v in (k.rawValue, v) }),
forKey: .workspaceTools)
try container.encode(Dictionary(uniqueKeysWithValues: self.activeTools.map { k, v in (k.rawValue, v) }),
forKey: .activeTools)
Keys.Appearance.key: self.appearance.dict(), try container.encode(self.appearance, forKey: .appearance)
Keys.WorkspaceTool.key: self.tools.mapToDict { ($0.rawValue, $1.dict()) }, try container.encode(self.orderedTools, forKey: .orderedTools)
try container.encode(self.previewTool, forKey: .previewTool)
Keys.MainWindow.isLeftOptionMeta: self.isLeftOptionMeta,
Keys.MainWindow.isRightOptionMeta: self.isRightOptionMeta,
Keys.MainWindow.orderedTools: self.orderedTools.map { $0.rawValue },
Keys.MainWindow.activeTools: self.activeTools.mapToDict { ($0.rawValue, $1) },
Keys.PreviewTool.key: self.previewTool.dict(),
Keys.MainWindow.isShowHidden: self.fileBrowserShowHidden,
Keys.MainWindow.useInteractiveZsh: self.useInteractiveZsh,
]
} }
} }
} }
struct WorkspaceToolState: SerializableState { struct WorkspaceToolState: Codable {
static let `default` = [ static let `default` = WorkspaceToolState()
MainWindow.Tools.fileBrowser: WorkspaceToolState(location: .left, dimension: 200, open: true),
MainWindow.Tools.buffersList: WorkspaceToolState(location: .left, dimension: 200, open: false),
MainWindow.Tools.preview: WorkspaceToolState(location: .right, dimension: 250, open: false),
MainWindow.Tools.htmlPreview: WorkspaceToolState(location: .right, dimension: 500, open: false),
]
static let `orderedDefault` = [ enum CodingKeys: String, CodingKey {
MainWindow.Tools.fileBrowser,
MainWindow.Tools.buffersList, case location = "location"
MainWindow.Tools.preview, case `open` = "is-visible"
MainWindow.Tools.htmlPreview, case dimension = "dimension"
] }
var location = WorkspaceBarLocation.left var location = WorkspaceBarLocation.left
var dimension = CGFloat(200) var dimension = CGFloat(200)
var open = false var open = false
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.location = try container.decode(forKey: .location, default: WorkspaceToolState.default.location)
self.dimension = CGFloat(try container.decode(forKey: .dimension, default: WorkspaceToolState.default.dimension))
self.open = try container.decode(forKey: .open, default: WorkspaceToolState.default.open)
}
// Use generated encode(to:)
private init() {
}
init(location: WorkspaceBarLocation, dimension: CGFloat, open: Bool) { init(location: WorkspaceBarLocation, dimension: CGFloat, open: Bool) {
self.location = location self.location = location
self.dimension = dimension self.dimension = dimension
self.open = open self.open = open
} }
init?(dict: [String: Any]) {
guard let locationRawValue = dict[Keys.WorkspaceTool.location] as? String,
let isOpen = PrefUtils.bool(from: dict, for: Keys.WorkspaceTool.open),
let fDimension = PrefUtils.float(from: dict, for: Keys.WorkspaceTool.dimension)
else {
return nil
}
guard let location = WorkspaceBarLocation(rawValue: locationRawValue) else {
return nil
}
self.location = location
self.dimension = CGFloat(fDimension)
self.open = isOpen
}
func dict() -> [String: Any] {
return [
Keys.WorkspaceTool.location: self.location.rawValue,
Keys.WorkspaceTool.open: self.open,
Keys.WorkspaceTool.dimension: Float(self.dimension),
]
}
} }
extension PreviewTool { extension PreviewTool {
struct State: SerializableState { struct State: Codable {
static let `default` = State() static let `default` = State()
enum CodingKeys: String, CodingKey {
case forwardSearchAutomatically = "is-forward-search-automatically"
case reverseSearchAutomatically = "is-reverse-search-automatically"
case refreshOnWrite = "is-refresh-on-write"
}
var isForwardSearchAutomatically = false var isForwardSearchAutomatically = false
var isReverseSearchAutomatically = false var isReverseSearchAutomatically = false
var isRefreshOnWrite = true var isRefreshOnWrite = true
init() { private init() {
} }
init?(dict: [String: Any]) { init(from decoder: Decoder) throws {
guard let isForward = PrefUtils.bool(from: dict, for: Keys.PreviewTool.forwardSearchAutomatically), let container = try decoder.container(keyedBy: CodingKeys.self)
let isReverse = PrefUtils.bool(from: dict, for: Keys.PreviewTool.reverseSearchAutomatically),
let isRefreshOnWrite = PrefUtils.bool(from: dict, for: Keys.PreviewTool.refreshOnWrite)
else {
return nil
}
self.isRefreshOnWrite = isRefreshOnWrite self.isForwardSearchAutomatically = try container.decode(forKey: .forwardSearchAutomatically,
self.isForwardSearchAutomatically = isForward default: State.default.isForwardSearchAutomatically)
self.isReverseSearchAutomatically = isReverse self.isReverseSearchAutomatically = try container.decode(forKey: .reverseSearchAutomatically,
default: State.default.isReverseSearchAutomatically)
self.isRefreshOnWrite = try container.decode(forKey: .refreshOnWrite, default: State.default.isRefreshOnWrite)
} }
func dict() -> [String: Any] { func encode(to encoder: Encoder) throws {
return [ var container = encoder.container(keyedBy: CodingKeys.self)
Keys.PreviewTool.forwardSearchAutomatically: self.isForwardSearchAutomatically,
Keys.PreviewTool.reverseSearchAutomatically: self.isReverseSearchAutomatically, try container.encode(self.isForwardSearchAutomatically, forKey: .forwardSearchAutomatically)
Keys.PreviewTool.refreshOnWrite: self.isRefreshOnWrite, try container.encode(self.isReverseSearchAutomatically, forKey: .reverseSearchAutomatically)
] try container.encode(self.isRefreshOnWrite, forKey: .refreshOnWrite)
} }
} }
} }
fileprivate extension KeyedDecodingContainer where K: CodingKey {
fileprivate func decode<T: Decodable>(forKey key: K, `default`: T) throws -> T {
return try self.decodeIfPresent(T.self, forKey: key) ?? `default`
}
}
/**
[1] Swift 4.2 has a bug: Only when a `Dictionary` has `String` or `Int` keys, it is encoded to dictionary.
This means that `Dictionary`s with `enum SomeEnum: String, Codable` keys are encoded as `Array`s.
The same problem persists also for decoding.
<https://forums.swift.org/t/json-encoding-decoding-weird-encoding-of-dictionary-with-enum-values/12995>
*/

View File

@ -6,7 +6,7 @@
import Cocoa import Cocoa
import PureLayout import PureLayout
enum WorkspaceBarLocation: String { enum WorkspaceBarLocation: String, Codable {
case top = "top" case top = "top"
case right = "right" case right = "right"

View File

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

View File

@ -7,22 +7,22 @@
<description>Most recent changes with links to updates for VimR.</description> <description>Most recent changes with links to updates for VimR.</description>
<language>en</language> <language>en</language>
<item> <item>
<title>SNAPSHOT-284</title> <title>SNAPSHOT-285</title>
<description><![CDATA[ <description><![CDATA[
<ul> <ul>
<li>GH-443: <code>vimr --line ${LINE_NUMBER} ${SOME_FILE}</code> will open the file and go to the given line. If the file is already open in a UI window, then that window will be selected and the cursor will be moved to the given line. This can be used e.g. to reverse-search LaTeX. Note that you have to re-install the <code>vimr</code> tool.</li> <li>GH-603: Bugfix: <code>Cmd-V</code> pastes at the wrong location in the insert mode.</li>
</ul> </ul>
]]></description> ]]></description>
<releaseNotesLink> <releaseNotesLink>
https://github.com/qvacua/vimr/releases/tag/snapshot/284 https://github.com/qvacua/vimr/releases/tag/snapshot/285
</releaseNotesLink> </releaseNotesLink>
<pubDate>2018-07-06T21:01:36.974431</pubDate> <pubDate>2018-07-15T22:07:13.166982</pubDate>
<minimumSystemVersion>10.10.0</minimumSystemVersion> <minimumSystemVersion>10.10.0</minimumSystemVersion>
<enclosure url="https://github.com/qvacua/vimr/releases/download/snapshot/284/VimR-SNAPSHOT-284.tar.bz2" <enclosure url="https://github.com/qvacua/vimr/releases/download/snapshot/285/VimR-SNAPSHOT-285.tar.bz2"
sparkle:version="284" sparkle:version="285"
sparkle:shortVersionString="SNAPSHOT-284" sparkle:shortVersionString="SNAPSHOT-285"
sparkle:dsaSignature="MC4CFQC85W5DOK+chBghYPusLQGPdfrXWAIVAOKVRd3YSnGyXJ3w5S3F7LU4vJTM" sparkle:dsaSignature="MC0CFHyBjevzdZbw+AXyogsP2oPp4qCuAhUApBfhVtzcySv3hMPmKo0oaWTBDuo="
length="14182159" length="14797431"
type="application/octet-stream"/> type="application/octet-stream"/>
</item> </item>
</channel> </channel>

View File

@ -2,6 +2,7 @@
* GH-625: `vimr --cur-env` will pass the current environment variables to the new neovim process. This will result in `virtualenv` support. * GH-625: `vimr --cur-env` will pass the current environment variables to the new neovim process. This will result in `virtualenv` support.
* GH-443: `vimr --line ${LINE_NUMBER} ${SOME_FILE}` will open the file and go to the given line. If the file is already open in a UI window, then that window will be selected and the cursor will be moved to the given line. This can be used e.g. to reverse-search LaTeX. * GH-443: `vimr --line ${LINE_NUMBER} ${SOME_FILE}` will open the file and go to the given line. If the file is already open in a UI window, then that window will be selected and the cursor will be moved to the given line. This can be used e.g. to reverse-search LaTeX.
* GH-603: Bugfix: `Cmd-V` pastes at the wrong location in the insert mode.
* Dependencies updates: * Dependencies updates:
- ReactiveX/RxSwift@4.2.0 - ReactiveX/RxSwift@4.2.0
- httpswift/swifter@1.4.2 - httpswift/swifter@1.4.2