Skip to content

Commit

Permalink
Merge pull request #345 from swiftbar/firstclass_shortcuts
Browse files Browse the repository at this point in the history
First class Shortcuts support
  • Loading branch information
melonamin authored Nov 8, 2022
2 parents 14f508d + 93ef2f2 commit d8be7c7
Show file tree
Hide file tree
Showing 23 changed files with 633 additions and 91 deletions.
36 changes: 24 additions & 12 deletions SwiftBar.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
39E1549F2569A2D700287D8A /* ImageVIew.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39E1549E2569A2D700287D8A /* ImageVIew.swift */; };
ABF91B7D2589C7920020590A /* NSFont+Offset.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABF91B7C2589C7920020590A /* NSFont+Offset.swift */; };
FA06104625F0564400B08B6E /* PluginEntryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA06104525F0564400B08B6E /* PluginEntryView.swift */; };
FA136A542917EE0700A7D712 /* PluginUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA136A532917EE0700A7D712 /* PluginUtilities.swift */; };
FA57F2A4272A307900817A79 /* XbarAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39B64C3E26152F5E00B7FA63 /* XbarAPI.swift */; };
FA57F2A5272A308F00817A79 /* DisablePluginIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAA14A142728C6FC0052FDB8 /* DisablePluginIntentHandler.swift */; };
FA57F2A6272A308F00817A79 /* EnablePluginIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAA14A102728C6E90052FDB8 /* EnablePluginIntentHandler.swift */; };
Expand All @@ -115,6 +116,8 @@
FA64C9DF25CF691D00C4E5C5 /* GeneralPreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA64C9DE25CF691D00C4E5C5 /* GeneralPreferencesView.swift */; };
FA64C9E225CF696D00C4E5C5 /* PluginsPreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA64C9E125CF696D00C4E5C5 /* PluginsPreferencesView.swift */; };
FA69F5BC2791145E00D6DDC6 /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA69F5BB2791145E00D6DDC6 /* WebView.swift */; };
FA6E13862915B70E00BA4594 /* ShortcutPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA6E13852915B70E00BA4594 /* ShortcutPlugin.swift */; };
FA6E13882915B81400BA4594 /* ShortcutsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA6E13872915B81400BA4594 /* ShortcutsManager.swift */; };
FA8518CC258DAAAB008AD21C /* Binding+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA8518CB258DAAAB008AD21C /* Binding+Extension.swift */; };
FA8518F52598E786008AD21C /* SwifCron in Frameworks */ = {isa = PBXBuildFile; productRef = FA8518F42598E786008AD21C /* SwifCron */; };
FA90185927C318A700D72E63 /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = FA90185827C318A700D72E63 /* Sparkle */; };
Expand All @@ -124,7 +127,8 @@
FAA14A152728C6FC0052FDB8 /* DisablePluginIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAA14A142728C6FC0052FDB8 /* DisablePluginIntentHandler.swift */; };
FAA14A172728C79B0052FDB8 /* GetPluginsIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAA14A162728C79B0052FDB8 /* GetPluginsIntentHandler.swift */; };
FAA14A192728C7FC0052FDB8 /* AppDelegate+Intents.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAA14A182728C7FC0052FDB8 /* AppDelegate+Intents.swift */; };
FABE059728C4035200093A83 /* AppCenterCrashes in Frameworks */ = {isa = PBXBuildFile; productRef = FABE059628C4035200093A83 /* AppCenterCrashes */; };
FAC3F2ED2915D88300D8F346 /* ShortcutPluginsPreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC3F2EC2915D88300D8F346 /* ShortcutPluginsPreferencesView.swift */; };
FAC3F2F12916A61800D8F346 /* AboutSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC3F2F02916A61800D8F346 /* AboutSettingsView.swift */; };
FAD14C052585AE1800CB7BBE /* String+ANSIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAD14C042585AE1800CB7BBE /* String+ANSIColor.swift */; };
FAD1BC9B25D22E9400B761E8 /* PluginDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAD1BC9A25D22E9400B761E8 /* PluginDetailsView.swift */; };
FAD1BC9E25D22EEA00B761E8 /* AnimatableWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAD1BC9D25D22EEA00B761E8 /* AnimatableWindow.swift */; };
Expand Down Expand Up @@ -197,20 +201,25 @@
39E1549E2569A2D700287D8A /* ImageVIew.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageVIew.swift; sourceTree = "<group>"; };
ABF91B7C2589C7920020590A /* NSFont+Offset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSFont+Offset.swift"; sourceTree = "<group>"; };
FA06104525F0564400B08B6E /* PluginEntryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PluginEntryView.swift; sourceTree = "<group>"; };
FA136A532917EE0700A7D712 /* PluginUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PluginUtilities.swift; sourceTree = "<group>"; };
FA3C3793281EB2760003DEDE /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
FA3C3794281EB27B0003DEDE /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
FA58E39927AD855D0034837F /* SystemNotificationName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemNotificationName.swift; sourceTree = "<group>"; };
FA60506726B593FA001A939A /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = "<group>"; };
FA64C9DE25CF691D00C4E5C5 /* GeneralPreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralPreferencesView.swift; sourceTree = "<group>"; };
FA64C9E125CF696D00C4E5C5 /* PluginsPreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PluginsPreferencesView.swift; sourceTree = "<group>"; };
FA69F5BB2791145E00D6DDC6 /* WebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebView.swift; sourceTree = "<group>"; };
FA6E13852915B70E00BA4594 /* ShortcutPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutPlugin.swift; sourceTree = "<group>"; };
FA6E13872915B81400BA4594 /* ShortcutsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutsManager.swift; sourceTree = "<group>"; };
FA8518CB258DAAAB008AD21C /* Binding+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Binding+Extension.swift"; sourceTree = "<group>"; };
FAA14A0D2728C65D0052FDB8 /* Intents.intentdefinition */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; path = Intents.intentdefinition; sourceTree = "<group>"; };
FAA14A102728C6E90052FDB8 /* EnablePluginIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnablePluginIntentHandler.swift; sourceTree = "<group>"; };
FAA14A122728C6F20052FDB8 /* ReloadPluginIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReloadPluginIntentHandler.swift; sourceTree = "<group>"; };
FAA14A142728C6FC0052FDB8 /* DisablePluginIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisablePluginIntentHandler.swift; sourceTree = "<group>"; };
FAA14A162728C79B0052FDB8 /* GetPluginsIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetPluginsIntentHandler.swift; sourceTree = "<group>"; };
FAA14A182728C7FC0052FDB8 /* AppDelegate+Intents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+Intents.swift"; sourceTree = "<group>"; };
FAC3F2EC2915D88300D8F346 /* ShortcutPluginsPreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutPluginsPreferencesView.swift; sourceTree = "<group>"; };
FAC3F2F02916A61800D8F346 /* AboutSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutSettingsView.swift; sourceTree = "<group>"; };
FAD14C042585AE1800CB7BBE /* String+ANSIColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+ANSIColor.swift"; sourceTree = "<group>"; };
FAD1BC9A25D22E9400B761E8 /* PluginDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PluginDetailsView.swift; sourceTree = "<group>"; };
FAD1BC9D25D22EEA00B761E8 /* AnimatableWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimatableWindow.swift; sourceTree = "<group>"; };
Expand All @@ -224,7 +233,6 @@
buildActionMask = 2147483647;
files = (
FA90185927C318A700D72E63 /* Sparkle in Frameworks */,
FABE059728C4035200093A83 /* AppCenterCrashes in Frameworks */,
3989359625896DF9007CF2E8 /* LaunchAtLogin in Frameworks */,
39B64C29260F70D900B7FA63 /* Preferences in Frameworks */,
FA8518F52598E786008AD21C /* SwifCron in Frameworks */,
Expand Down Expand Up @@ -358,6 +366,7 @@
39AF7771254612BF001D76E5 /* PluginMetadata.swift */,
39AF7774254613C9001D76E5 /* PluginManger.swift */,
3990DCE02602BB5B002CDCD5 /* PluginDebugInfo.swift */,
FA6E13852915B70E00BA4594 /* ShortcutPlugin.swift */,
);
path = Plugin;
sourceTree = "<group>";
Expand Down Expand Up @@ -395,6 +404,8 @@
39224DD425F414F500BABF21 /* Notification+Extension.swift */,
39224E5B25F530AF00BABF21 /* Environment.swift */,
FA58E39927AD855D0034837F /* SystemNotificationName.swift */,
FA6E13872915B81400BA4594 /* ShortcutsManager.swift */,
FA136A532917EE0700A7D712 /* PluginUtilities.swift */,
);
path = Utility;
sourceTree = "<group>";
Expand All @@ -406,6 +417,8 @@
FA64C9DE25CF691D00C4E5C5 /* GeneralPreferencesView.swift */,
FA64C9E125CF696D00C4E5C5 /* PluginsPreferencesView.swift */,
FAD1BC9A25D22E9400B761E8 /* PluginDetailsView.swift */,
FAC3F2EC2915D88300D8F346 /* ShortcutPluginsPreferencesView.swift */,
FAC3F2F02916A61800D8F346 /* AboutSettingsView.swift */,
);
path = Preferences;
sourceTree = "<group>";
Expand Down Expand Up @@ -463,7 +476,6 @@
FA8518F42598E786008AD21C /* SwifCron */,
39B64C28260F70D900B7FA63 /* Preferences */,
FA90185827C318A700D72E63 /* Sparkle */,
FABE059628C4035200093A83 /* AppCenterCrashes */,
);
productName = SwiftBar;
productReference = 3920747A25460FD000213DBE /* SwiftBar.app */;
Expand Down Expand Up @@ -715,6 +727,8 @@
3990DCDA2602BB32002CDCD5 /* DebugView.swift in Sources */,
39E1549C25699C8F00287D8A /* URLTextView.swift in Sources */,
FAD1BC9B25D22E9400B761E8 /* PluginDetailsView.swift in Sources */,
FAC3F2ED2915D88300D8F346 /* ShortcutPluginsPreferencesView.swift in Sources */,
FAC3F2F12916A61800D8F346 /* AboutSettingsView.swift in Sources */,
39224DCF25F3E6DE00BABF21 /* AppDelegate+Menu.swift in Sources */,
3920747E25460FD000213DBE /* AppDelegate.swift in Sources */,
393375E725507ADE0050AC28 /* Log.swift in Sources */,
Expand All @@ -726,12 +740,14 @@
398DAE7A25537DAF00747D90 /* PluginErrorView.swift in Sources */,
396257262569667000341A19 /* PluginRepositoryView.swift in Sources */,
39AF7778254613FB001D76E5 /* ExecutablePlugin.swift in Sources */,
FA6E13862915B70E00BA4594 /* ShortcutPlugin.swift in Sources */,
396E6CB0258E8D47002C735D /* Localizable.swift in Sources */,
FA58E39A27AD855D0034837F /* SystemNotificationName.swift in Sources */,
39AF77842547750E001D76E5 /* AppShared.swift in Sources */,
FAA14A0E2728C65D0052FDB8 /* Intents.intentdefinition in Sources */,
39641EA1254DD32100713DAF /* AboutPluginView.swift in Sources */,
39AF7793254B5834001D76E5 /* NSColor.swift in Sources */,
FA136A542917EE0700A7D712 /* PluginUtilities.swift in Sources */,
398B86C4254DA85300DEA027 /* URL+Extension.swift in Sources */,
FAA14A192728C7FC0052FDB8 /* AppDelegate+Intents.swift in Sources */,
39AF778D2548EBA3001D76E5 /* MenuLineParameters.swift in Sources */,
Expand All @@ -741,6 +757,7 @@
ABF91B7D2589C7920020590A /* NSFont+Offset.swift in Sources */,
398B86CA254DB5D200DEA027 /* DirectoryObserver.swift in Sources */,
39B84A22257D63F700FA012E /* NSMutableAttributedString+SFSymbols.swift in Sources */,
FA6E13882915B81400BA4594 /* ShortcutsManager.swift in Sources */,
39224E5C25F530AF00BABF21 /* Environment.swift in Sources */,
FAA14A112728C6E90052FDB8 /* EnablePluginIntentHandler.swift in Sources */,
39224DD225F3F19B00BABF21 /* AppDelegate+Toolbar.swift in Sources */,
Expand Down Expand Up @@ -963,7 +980,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 445;
CURRENT_PROJECT_VERSION = 461;
DEVELOPMENT_ASSET_PATHS = "\"SwiftBar/Preview Content\"";
DEVELOPMENT_TEAM = X93LWC49WV;
ENABLE_HARDENED_RUNTIME = YES;
Expand All @@ -974,7 +991,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 1.4.4;
MARKETING_VERSION = 1.5.0;
PRODUCT_BUNDLE_IDENTIFIER = com.ameba.SwiftBar;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
Expand All @@ -990,7 +1007,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 445;
CURRENT_PROJECT_VERSION = 461;
DEVELOPMENT_ASSET_PATHS = "\"SwiftBar/Preview Content\"";
DEVELOPMENT_TEAM = X93LWC49WV;
ENABLE_HARDENED_RUNTIME = YES;
Expand All @@ -1001,7 +1018,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 1.4.4;
MARKETING_VERSION = 1.5.0;
PRODUCT_BUNDLE_IDENTIFIER = com.ameba.SwiftBar;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
Expand Down Expand Up @@ -1218,11 +1235,6 @@
package = FA90185727C318A700D72E63 /* XCRemoteSwiftPackageReference "Sparkle" */;
productName = Sparkle;
};
FABE059628C4035200093A83 /* AppCenterCrashes */ = {
isa = XCSwiftPackageProductDependency;
package = FABE059528C4035200093A83 /* XCRemoteSwiftPackageReference "appcenter-sdk-apple" */;
productName = AppCenterCrashes;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 3920747225460FD000213DBE /* Project object */;
Expand Down
12 changes: 6 additions & 6 deletions SwiftBar/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import UserNotifications
#else
import Sparkle
#endif
import AppCenter
import AppCenterCrashes
// import AppCenter
// import AppCenterCrashes

class AppDelegate: NSObject, NSApplicationDelegate, SPUStandardUserDriverDelegate, SPUUpdaterDelegate, UNUserNotificationCenterDelegate, NSWindowDelegate {
var repositoryWindowController: NSWindowController? {
Expand All @@ -35,9 +35,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, SPUStandardUserDriverDelegat
func applicationDidFinishLaunching(_: Notification) {
if prefs.collectCrashReports {
// Not cool to have the KEY here, but since this is for crash reporting I don't care
AppCenter.start(withAppSecret: "40e6c2fa-2383-40a7-bfbd-75662a7d92a9", services: [
Crashes.self,
])
// AppCenter.start(withAppSecret: "40e6c2fa-2383-40a7-bfbd-75662a7d92a9", services: [
// Crashes.self,
// ])
}
preferencesWindowController.window?.delegate = self
setupToolbar()
Expand Down Expand Up @@ -102,7 +102,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, SPUStandardUserDriverDelegat
}

func setDefaultShelf() {
// let out = try? runScript(to: "dscl", args: [".", "-read", "~/", "UserShell", "|", "awk", "'{print $2}'"])
let out = try? runScript(to: "echo", args: ["$SHELL"])
if let shell = out?.out, shell != "" {
sharedEnv.userLoginShell = shell.trimmingCharacters(in: .newlines)
Expand Down Expand Up @@ -144,6 +143,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, SPUStandardUserDriverDelegat
pluginManager.refreshAllPlugins()
case "refreshplugin":
if let plugin = getPluginFromURL(url: url) {
pluginManager.menuBarItems[plugin.id]?.dimOnManualRefresh()
plugin.refresh()
return
}
Expand Down
48 changes: 5 additions & 43 deletions SwiftBar/Plugin/ExecutablePlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ class ExecutablePlugin: Plugin {
var lastUpdated: Date?
var lastState: PluginState
var contentUpdatePublisher = PassthroughSubject<String?, Never>()
var operation: ExecutablePluginOperation?
var operation: RunPluginOperation<ExecutablePlugin>?

var content: String? = "..." {
didSet {
contentUpdatePublisher.send(content)
}
}

var error: ShellOutError?
var error: Error?
var debugInfo = PluginDebugInfo()

lazy var invokeQueue: OperationQueue = delegate.pluginManager.pluginInvokeQueue
Expand All @@ -47,36 +47,13 @@ class ExecutablePlugin: Plugin {
refreshPluginMetadata()

if metadata?.nextDate == nil, nameComponents.count > 2 {
updateInterval = nameComponents.dropFirst().compactMap { parseRefreshInterval(intervalStr: $0) }.reduce(updateInterval, min)
updateInterval = nameComponents.dropFirst().compactMap { parseRefreshInterval(intervalStr: $0, baseUpdateinterval: updateInterval) }.reduce(updateInterval, min)
}
createSupportDirs()
os_log("Initialized executable plugin\n%{public}@", log: Log.plugin, description)
refresh()
}

func parseRefreshInterval(intervalStr: String) -> Double? {
guard let interval = Double(intervalStr.filter("0123456789.".contains)) else { return nil }
var updateInterval: Double = self.updateInterval

if intervalStr.hasSuffix("s") {
updateInterval = interval
if intervalStr.hasSuffix("ms") {
updateInterval = interval / 1000
}
}
if intervalStr.hasSuffix("m") {
updateInterval = interval * 60
}
if intervalStr.hasSuffix("h") {
updateInterval = interval * 60 * 60
}
if intervalStr.hasSuffix("d") {
updateInterval = interval * 60 * 60 * 24
}

return updateInterval
}

// this function called each time plugin updated(manual or scheduled)
func enableTimer() {
// handle cron scheduled plugins
Expand All @@ -93,7 +70,7 @@ class ExecutablePlugin: Plugin {
.autoconnect()
.receive(on: invokeQueue)
.sink(receiveValue: { [weak self] _ in
self?.invokeQueue.addOperation(ExecutablePluginOperation(plugin: self!))
self?.invokeQueue.addOperation(RunPluginOperation<ExecutablePlugin>(plugin: self!))
}).store(in: &cancellable)
}

Expand Down Expand Up @@ -132,7 +109,7 @@ class ExecutablePlugin: Plugin {
operation?.cancel()

refreshPluginMetadata()
operation = ExecutablePluginOperation(plugin: self)
operation = RunPluginOperation<ExecutablePlugin>(plugin: self)
invokeQueue.addOperation(operation!)
}

Expand Down Expand Up @@ -165,18 +142,3 @@ class ExecutablePlugin: Plugin {
refresh()
}
}

final class ExecutablePluginOperation: Operation {
weak var plugin: ExecutablePlugin?

init(plugin: ExecutablePlugin) {
self.plugin = plugin
super.init()
}

override func main() {
guard !isCancelled else { return }
plugin?.content = plugin?.invoke()
plugin?.enableTimer()
}
}
3 changes: 2 additions & 1 deletion SwiftBar/Plugin/Plugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import os
enum PluginType: String {
case Executable
case Streamable
case Shortcut
}

enum PluginState {
Expand All @@ -29,7 +30,7 @@ protocol Plugin: AnyObject {
var lastUpdated: Date? { get set }
var lastState: PluginState { get set }
var content: String? { get set }
var error: ShellOutError? { get set }
var error: Error? { get set }
var debugInfo: PluginDebugInfo { get set }
func refresh()
func enable()
Expand Down
Loading

0 comments on commit d8be7c7

Please sign in to comment.