diff --git a/Sources/XiEditor/Client.swift b/Sources/XiEditor/Client.swift
index 6c164225..c6511e63 100644
--- a/Sources/XiEditor/Client.swift
+++ b/Sources/XiEditor/Client.swift
@@ -86,4 +86,7 @@ protocol XiClient: AnyObject {
/// A notification containing the current replace status.
func replaceStatus(viewIdentifier: String, status: ReplaceStatus)
+
+ /// A notification telling whether tail was enabled/disabled.
+ func enableTailing(viewIdentifier: String, isTailEnabled: Bool)
}
diff --git a/Sources/XiEditor/ClientImplementation.swift b/Sources/XiEditor/ClientImplementation.swift
index 02cfa0c9..b514390d 100644
--- a/Sources/XiEditor/ClientImplementation.swift
+++ b/Sources/XiEditor/ClientImplementation.swift
@@ -176,6 +176,14 @@ class ClientImplementation: XiClient, DocumentsProviding, ConfigCacheProviding,
}
}
}
+
+ func enableTailing(viewIdentifier: String, isTailEnabled: Bool) {
+ let document = documentForViewIdentifier(viewIdentifier: viewIdentifier)
+ DispatchQueue.main.async {
+ document?.editViewController?.enableTailing(isTailEnabled)
+ }
+ }
+
// Stores the config dict so new windows don't have to wait for core to send it.
// The main purpose of this is ensuring that `unified_titlebar` applies immediately.
diff --git a/Sources/XiEditor/Core/CoreNotification.swift b/Sources/XiEditor/Core/CoreNotification.swift
index d7422565..e42e3971 100644
--- a/Sources/XiEditor/Core/CoreNotification.swift
+++ b/Sources/XiEditor/Core/CoreNotification.swift
@@ -71,6 +71,7 @@ enum CoreNotification {
case findStatus(viewIdentifier: ViewIdentifier, status: [FindStatus])
case replaceStatus(viewIdentifier: ViewIdentifier, status: ReplaceStatus)
+ case enableTailing(viewIdentifier: ViewIdentifier, isTailEnabled: Bool)
static func fromJson(_ json: [String: Any]) -> CoreNotification? {
guard
@@ -228,6 +229,11 @@ enum CoreNotification {
{
return .replaceStatus(viewIdentifier: viewIdentifier!, status: replaceStatus)
}
+ case "enable_tailing":
+ if let isTailEnabled = jsonParams["is_tail_enabled"] as? Bool
+ {
+ return .enableTailing(viewIdentifier: viewIdentifier!, isTailEnabled: isTailEnabled)
+ }
default:
assertionFailure("Unsupported notification method from core: \(jsonMethod)")
diff --git a/Sources/XiEditor/EditViewController.swift b/Sources/XiEditor/EditViewController.swift
index d4db2b66..695e86e3 100644
--- a/Sources/XiEditor/EditViewController.swift
+++ b/Sources/XiEditor/EditViewController.swift
@@ -152,6 +152,11 @@ class EditViewController: NSViewController, EditViewDataSource, FindDelegate, Sc
updateLanguageMenu()
}
}
+
+ /// Flag to determine if current file is being tailed.
+ var isTailEnabled: Bool = false
+
+ var isExistingFile: Bool = false
// used to calculate the gutter width. Initial -1 so that a new document
// still triggers update of gutter width.
@@ -329,6 +334,12 @@ class EditViewController: NSViewController, EditViewDataSource, FindDelegate, Sc
_previousViewportSize = CGSize.zero
redrawEverything()
}
+
+ func enableTailMenu() {
+ let toggleTailSubMenu = NSApplication.shared.mainMenu!.item(withTitle: "Debug")!.submenu!.item(withTitle: "Tail File")
+ toggleTailSubMenu!.isEnabled = true
+ self.isExistingFile = true
+ }
/// If font size or theme changes, we invalidate all views.
func redrawEverything() {
@@ -711,6 +722,10 @@ class EditViewController: NSViewController, EditViewDataSource, FindDelegate, Sc
document.xiCore.setTheme(themeName: sender.title)
}
+ @IBAction func debugToggleTail(_ sender: NSMenuItem) {
+ document.xiCore.toggleTailConfig(identifier: document.coreViewIdentifier!, enabled: !self.isTailEnabled)
+ }
+
@IBAction func debugSetLanguage(_ sender: NSMenuItem) {
guard sender.state != NSControl.StateValue.on else { print("language already active"); return }
document.xiCore.setLanguage(identifier: document.coreViewIdentifier!, languageName: sender.title)
@@ -840,11 +855,28 @@ class EditViewController: NSViewController, EditViewDataSource, FindDelegate, Sc
item.state = findViewController.showMultipleSearchQueries ? .on : .off
}
+ func updateTailMenu() {
+ let toggleTailSubMenu = NSApplication.shared.mainMenu!.item(withTitle: "Debug")!.submenu!.item(withTitle: "Tail File")
+ if self.isExistingFile {
+ toggleTailSubMenu!.isEnabled = true
+ if self.isTailEnabled {
+ toggleTailSubMenu!.state = NSControl.StateValue.on
+ } else {
+ toggleTailSubMenu!.state = NSControl.StateValue.off
+ }
+ } else {
+ toggleTailSubMenu!.isEnabled = false
+ toggleTailSubMenu!.state = NSControl.StateValue.off
+ self.isTailEnabled = false
+ }
+ }
+
// Gets called when active window changes
func updateMenuState() {
updatePluginMenu()
updateLanguageMenu()
updateFindMenu()
+ updateTailMenu()
}
@objc func handleCommand(_ sender: NSMenuItem) {
@@ -919,6 +951,11 @@ class EditViewController: NSViewController, EditViewDataSource, FindDelegate, Sc
languagesMenu.addItem(item)
}
}
+
+ public func enableTailing(_ isTailEnabled: Bool) {
+ self.isTailEnabled = isTailEnabled
+ self.updateTailMenu()
+ }
@IBAction func gotoLine(_ sender: AnyObject) {
guard let window = self.view.window else { return }
diff --git a/Sources/XiEditor/Main.storyboard b/Sources/XiEditor/Main.storyboard
index 1dfe620d..c802a991 100644
--- a/Sources/XiEditor/Main.storyboard
+++ b/Sources/XiEditor/Main.storyboard
@@ -1111,7 +1111,7 @@ Gw
@@ -1238,6 +1244,7 @@ Gw
+
diff --git a/Sources/XiEditor/RPCSending.swift b/Sources/XiEditor/RPCSending.swift
index 7dcc44bb..88d6331b 100644
--- a/Sources/XiEditor/RPCSending.swift
+++ b/Sources/XiEditor/RPCSending.swift
@@ -309,6 +309,8 @@ class StdoutRPCSender: RPCSending {
self.client?.findStatus(viewIdentifier: viewIdentifier, status: status)
case let .replaceStatus(viewIdentifier, status):
self.client?.replaceStatus(viewIdentifier: viewIdentifier, status: status)
+ case let .enableTailing(viewIdentifier, isTailEnabled):
+ self.client?.enableTailing(viewIdentifier: viewIdentifier, isTailEnabled: isTailEnabled)
}
}
diff --git a/Sources/XiEditor/XiCore.swift b/Sources/XiEditor/XiCore.swift
index dd120d58..02dbbb4f 100644
--- a/Sources/XiEditor/XiCore.swift
+++ b/Sources/XiEditor/XiCore.swift
@@ -48,6 +48,9 @@ protocol XiCore: class {
/// `Document` calls are migrated to it's own protocol.
func sendRpcAsync(_ method: String, params: Any, callback: RpcCallback?)
func sendRpc(_ method: String, params: Any) -> RpcResult
+ /// Will tail opened file if enabled.
+ /// If toggle succeeds the client will receive a `toggle_tail_config_changed` notification.
+ func toggleTailConfig(identifier: ViewIdentifier, enabled: Bool)
}
final class CoreConnection: XiCore {
@@ -109,6 +112,10 @@ final class CoreConnection: XiCore {
let params = ["destination": destination, "frontend_samples": frontendSamples] as AnyObject
sendRpcAsync("save_trace", params: params)
}
+
+ func toggleTailConfig(identifier: ViewIdentifier, enabled: Bool) {
+ sendRpcAsync("toggle_tail", params: ["view_id": identifier, "enabled": enabled])
+ }
func sendRpcAsync(_ method: String, params: Any, callback: RpcCallback? = nil) {
rpcSender.sendRpcAsync(method, params: params, callback: callback)
diff --git a/Sources/XiEditor/XiDocumentController.swift b/Sources/XiEditor/XiDocumentController.swift
index 6a5a2a97..c7d875f4 100644
--- a/Sources/XiEditor/XiDocumentController.swift
+++ b/Sources/XiEditor/XiDocumentController.swift
@@ -133,6 +133,7 @@ class XiDocumentController: NSDocumentController, AlertPresenting {
currentDocument.fileURL = url
self.setIdentifier(result, forDocument: currentDocument)
currentDocument.editViewController!.prepareForReuse()
+ currentDocument.editViewController!.enableTailMenu()
completionHandler(currentDocument, false, nil)
case .error(let error):
@@ -182,6 +183,10 @@ class XiDocumentController: NSDocumentController, AlertPresenting {
let viewIdentifier = result as! String
self.setIdentifier(viewIdentifier, forDocument: document)
document.coreViewIdentifier = viewIdentifier
+ if url != nil {
+ document.editViewController?.isExistingFile = true
+ }
+ document.editViewController?.updateTailMenu()
case .error(let error):
document.close()
self.showAlert(with: error.message)
diff --git a/Tests/IntegrationTests/TestClientImplementation.swift b/Tests/IntegrationTests/TestClientImplementation.swift
index 4cde8f95..de395594 100644
--- a/Tests/IntegrationTests/TestClientImplementation.swift
+++ b/Tests/IntegrationTests/TestClientImplementation.swift
@@ -86,4 +86,7 @@ class TestClientImplementation: XiClient {
func replaceStatus(viewIdentifier: String, status: ReplaceStatus) {
}
+
+ func enableTailing(viewIdentifier: String, isTailEnabled: Bool) {
+ }
}