Skip to content

Commit

Permalink
Major update:
Browse files Browse the repository at this point in the history
- jump to absolute line number
- copy current absolute line number
- select/copy multiple lines to clipboard
- export selected lines
- export filtered result
- filter engine fixes
  • Loading branch information
alexhude committed Oct 16, 2020
1 parent 57e0cce commit c60b559
Show file tree
Hide file tree
Showing 17 changed files with 871 additions and 119 deletions.
4 changes: 4 additions & 0 deletions PeculiarLog.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@
CODE_SIGN_ENTITLEMENTS = PeculiarLog/PeculiarLog.entitlements;
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = "";
HEADER_SEARCH_PATHS = /usr/local/opt/hyperscan/include/hs;
INFOPLIST_FILE = PeculiarLog/Info.plist;
Expand All @@ -323,6 +324,7 @@
);
LIBRARY_SEARCH_PATHS = /usr/local/lib;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 1.2;
OTHER_LDFLAGS = "-lhs";
PRODUCT_BUNDLE_IDENTIFIER = tech.peculiar.PeculiarLog;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -342,6 +344,7 @@
CODE_SIGN_ENTITLEMENTS = PeculiarLog/PeculiarLog.entitlements;
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = "";
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
HEADER_SEARCH_PATHS = /usr/local/opt/hyperscan/include/hs;
Expand All @@ -352,6 +355,7 @@
);
LIBRARY_SEARCH_PATHS = /usr/local/lib;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 1.2;
OTHER_LDFLAGS = "-lhs";
PRODUCT_BUNDLE_IDENTIFIER = tech.peculiar.PeculiarLog;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down
31 changes: 31 additions & 0 deletions PeculiarLog/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,36 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
}

@IBAction func exportFiltered(_ sender: Any) {
print("[+] exporting filtered...")
let documentController = NSDocumentController.shared

let savePanel = NSSavePanel()
savePanel.canCreateDirectories = true
savePanel.showsTagField = false
savePanel.nameFieldStringValue = (documentController.currentDocument?.displayName)!
let res = savePanel.runModal()
if(res == NSApplication.ModalResponse.OK) {
if let fileName = savePanel.url {
(documentController.currentDocument as? Document)?.exportFiltered(fileName: fileName)
}
}
}

@IBAction func exportSelected(_ sender: Any) {
print("[+] exporting selected...")
let documentController = NSDocumentController.shared

let savePanel = NSSavePanel()
savePanel.canCreateDirectories = true
savePanel.showsTagField = false
savePanel.nameFieldStringValue = (documentController.currentDocument?.displayName)!
let res = savePanel.runModal()
if(res == NSApplication.ModalResponse.OK) {
if let fileName = savePanel.url {
(documentController.currentDocument as? Document)?.exportSelected(fileName: fileName)
}
}
}
}

152 changes: 113 additions & 39 deletions PeculiarLog/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

54 changes: 54 additions & 0 deletions PeculiarLog/Document.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,59 @@ class Document: NSDocument {
override func read(from url: URL, ofType typeName: String) throws {
searchEngine = SearchEngine(url.path)
}

func exportFiltered(fileName:URL) {
if let contentVC = self.windowControllers.first?.contentViewController as? ViewController {
do {
let fileHandle = FileHandle(forWritingAtPath: fileName.path)
if fileHandle == nil {
try "".write(to: fileName, atomically: true, encoding: String.Encoding.utf8)
}

if let fileHandle = FileHandle(forWritingAtPath: fileName.path) {
defer {
fileHandle.closeFile()
Swift.print("[+] saved to \(fileName.path)")
}
fileHandle.seekToEndOfFile()
contentVC.filteredContent(fileHandle)
}
} catch {
let alert = NSAlert()
alert.messageText = "PeculiarLog"
alert.informativeText = "Unable to export filtered content."
alert.alertStyle = NSAlert.Style.critical
alert.addButton(withTitle: "OK")
alert.runModal()
}
}
}

func exportSelected(fileName:URL) {
if let contentVC = self.windowControllers.first?.contentViewController as? ViewController {
do {
let fileHandle = FileHandle(forWritingAtPath: fileName.path)
if fileHandle == nil {
try "".write(to: fileName, atomically: true, encoding: String.Encoding.utf8)
}

if let fileHandle = FileHandle(forWritingAtPath: fileName.path) {
defer {
Swift.print("[+] saved to \(fileName.path)")
fileHandle.closeFile()
}
fileHandle.seekToEndOfFile()
contentVC.selectedContent(fileHandle)
}
} catch {
let alert = NSAlert()
alert.messageText = "PeculiarLog"
alert.informativeText = "Unable to export filtered content."
alert.alertStyle = NSAlert.Style.critical
alert.addButton(withTitle: "OK")
alert.runModal()
}
}
}
}

6 changes: 3 additions & 3 deletions PeculiarLog/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>1</string>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2019 Alexander Hude.
<string>Copyright © 2020 Alexander Hude.
All rights reserved.</string>
<key>NSMainStoryboardFile</key>
<string>Main</string>
Expand Down
74 changes: 71 additions & 3 deletions PeculiarLog/LogViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,17 @@

import Cocoa

public protocol LogViewDelegate {
func patternCompilationError(_ error: String)
func selectionChanged()
}

class LogViewController: NSViewController {

@IBOutlet var tableView: NSTableView!

var delegate: LogViewDelegate?

private var currentPattern: String = ""
private var currentMatchColor: NSColor = NSColor.red
private var currentScopeColor: NSColor = NSColor.textColor
Expand Down Expand Up @@ -60,13 +67,20 @@ class LogViewController: NSViewController {
tableView.tableColumns[cindex].isHidden = !show
}

func filterLog(with pattern: String, matchColor: NSColor, scopeColor: NSColor) {
func filterLog(with pattern: String, matchColor: NSColor, scopeColor: NSColor, reportError: Bool = false) {
guard let engine = self.representedObject as? SearchEngine else { return }
currentPattern = pattern
currentMatchColor = matchColor
currentScopeColor = scopeColor

guard engine.setPattern(pattern) else { return }
let (result, error) = engine.setPattern(pattern)
guard result else {
if (reportError) {
delegate?.patternCompilationError(error)
}
return
}

if (pattern.count != 0) {
guard engine.filter() else { return }
}
Expand All @@ -78,6 +92,39 @@ class LogViewController: NSViewController {
tableView.reloadData()
}

func gotoAbsLine(_ line: Int) -> Bool {
guard let engine = self.representedObject as? SearchEngine else { return false }

guard
line != 0,
line <= engine.totalLines
else { return false }

var row = 0
if (engine.isFiltered) {
row = engine.getRowForAbsLine(line)
guard row != -1 else { return false }
} else {
row = line - 1
}
tableView.scrollRowToVisible(row: row, animated: true)
return true;
}
}

extension NSTableView {
func scrollRowToVisible(row: Int, animated: Bool) {
self.selectRowIndexes(IndexSet.init(integer: row), byExtendingSelection: false)
let rowRect = self.frameOfCell(atColumn: 1, row: row)
if let scrollView = self.enclosingScrollView {
let centredPoint = NSMakePoint(0.0, rowRect.origin.y + (rowRect.size.height / 2) - ((scrollView.frame.size.height) / 2))
if animated {
scrollView.contentView.animator().setBoundsOrigin(centredPoint)
} else {
self.scroll(centredPoint)
}
}
}
}

extension String {
Expand All @@ -95,6 +142,27 @@ extension String {

extension LogViewController: NSTableViewDataSource, NSTableViewDelegate {

func tableViewSelectionDidChange(_ notification: Notification) {
delegate?.selectionChanged()
}

@objc func copy(_ sender: AnyObject) {
guard let engine = self.representedObject as? SearchEngine else { return; }

var selectedLines = ""
let indexSet = tableView.selectedRowIndexes

for (_, rowIndex) in indexSet.enumerated() {
let lineInfo = engine.getLine(rowIndex)
selectedLines += lineInfo.line
selectedLines += "\n"
}

let pasteBoard = NSPasteboard.general
pasteBoard.clearContents()
pasteBoard.setString(selectedLines, forType:NSPasteboard.PasteboardType.string)
}

func numberOfRows(in tableView: NSTableView) -> Int {
guard let engine = self.representedObject as? SearchEngine else { return 0 }
return engine.lineCount
Expand All @@ -111,7 +179,7 @@ extension LogViewController: NSTableViewDataSource, NSTableViewDelegate {
rowInfoCache = engine.getLine(row)
guard let lineInfo = rowInfoCache else { return nil; }

cell.textField?.stringValue = String(lineInfo.number + 1)
cell.textField?.stringValue = String(lineInfo.number)
cell.wantsLayer = true
cell.layer?.backgroundColor = NSColor(named: NSColor.Name("LineNumberBackgroundColor"))?.cgColor
return cell
Expand Down
8 changes: 4 additions & 4 deletions PeculiarLog/PeculiarLog.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
</dict>
</plist>
Loading

0 comments on commit c60b559

Please sign in to comment.