added a terminal

currently doesnt work
using runestone as the terminal
This commit is contained in:
neon443
2025-06-09 17:25:05 +01:00
parent 0b9287f2e7
commit d4e1660728
7 changed files with 159 additions and 11 deletions

View File

@@ -6,7 +6,7 @@
// //
VERSION = 0.1 VERSION = 0.1
BUILD = 1 BUILD = 3
// Configuration settings file format documentation can be found at: // Configuration settings file format documentation can be found at:
// https://developer.apple.com/documentation/xcode/adding-a-build-configuration-file-to-your-project // https://developer.apple.com/documentation/xcode/adding-a-build-configuration-file-to-your-project

View File

@@ -8,6 +8,13 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
A9083E402DF2226F0042906E /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = A9083E3F2DF2225A0042906E /* libz.tbd */; }; A9083E402DF2226F0042906E /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = A9083E3F2DF2225A0042906E /* libz.tbd */; };
A91AE38A2DF722A700FF3537 /* Runestone in Frameworks */ = {isa = PBXBuildFile; productRef = A91AE3892DF722A600FF3537 /* Runestone */; };
A91AE3B22DF73E0900FF3537 /* TerminalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91AE3B12DF73E0900FF3537 /* TerminalView.swift */; };
A91AE3B52DF73F1D00FF3537 /* TreeSitterBash in Frameworks */ = {isa = PBXBuildFile; productRef = A91AE3B42DF73F1D00FF3537 /* TreeSitterBash */; };
A91AE3B72DF73F1D00FF3537 /* TreeSitterBashQueries in Frameworks */ = {isa = PBXBuildFile; productRef = A91AE3B62DF73F1D00FF3537 /* TreeSitterBashQueries */; };
A91AE3B92DF73F1D00FF3537 /* TreeSitterBashRunestone in Frameworks */ = {isa = PBXBuildFile; productRef = A91AE3B82DF73F1D00FF3537 /* TreeSitterBashRunestone */; };
A91AE3BB2DF73F1D00FF3537 /* TreeSitterLanguagesCommon in Frameworks */ = {isa = PBXBuildFile; productRef = A91AE3BA2DF73F1D00FF3537 /* TreeSitterLanguagesCommon */; };
A91AE3BD2DF7402100FF3537 /* TextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91AE3BC2DF7402100FF3537 /* TextViewController.swift */; };
A92538C82DEE0742007E0A18 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538C52DEE0742007E0A18 /* ContentView.swift */; }; A92538C82DEE0742007E0A18 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538C52DEE0742007E0A18 /* ContentView.swift */; };
A92538C92DEE0742007E0A18 /* ShhShellApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538C62DEE0742007E0A18 /* ShhShellApp.swift */; }; A92538C92DEE0742007E0A18 /* ShhShellApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538C62DEE0742007E0A18 /* ShhShellApp.swift */; };
A92538CA2DEE0742007E0A18 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A92538C42DEE0742007E0A18 /* Assets.xcassets */; }; A92538CA2DEE0742007E0A18 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A92538C42DEE0742007E0A18 /* Assets.xcassets */; };
@@ -59,6 +66,8 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
A9083E3F2DF2225A0042906E /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; A9083E3F2DF2225A0042906E /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
A91AE3B12DF73E0900FF3537 /* TerminalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalView.swift; sourceTree = "<group>"; };
A91AE3BC2DF7402100FF3537 /* TextViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewController.swift; sourceTree = "<group>"; };
A925389A2DEE06DC007E0A18 /* ShhShell.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ShhShell.app; sourceTree = BUILT_PRODUCTS_DIR; }; A925389A2DEE06DC007E0A18 /* ShhShell.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ShhShell.app; sourceTree = BUILT_PRODUCTS_DIR; };
A92538A72DEE06DE007E0A18 /* ShhShellTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ShhShellTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; A92538A72DEE06DE007E0A18 /* ShhShellTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ShhShellTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
A92538B12DEE06DE007E0A18 /* ShhShellUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ShhShellUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; A92538B12DEE06DE007E0A18 /* ShhShellUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ShhShellUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -86,8 +95,13 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A91AE3B72DF73F1D00FF3537 /* TreeSitterBashQueries in Frameworks */,
A95FAA542DF4B62900DE2F5A /* LibSSH.xcframework in Frameworks */, A95FAA542DF4B62900DE2F5A /* LibSSH.xcframework in Frameworks */,
A91AE3B52DF73F1D00FF3537 /* TreeSitterBash in Frameworks */,
A91AE3B92DF73F1D00FF3537 /* TreeSitterBashRunestone in Frameworks */,
A91AE38A2DF722A700FF3537 /* Runestone in Frameworks */,
A93143BE2DF4D0B300FCD5DB /* libpthread.tbd in Frameworks */, A93143BE2DF4D0B300FCD5DB /* libpthread.tbd in Frameworks */,
A91AE3BB2DF73F1D00FF3537 /* TreeSitterLanguagesCommon in Frameworks */,
A9083E402DF2226F0042906E /* libz.tbd in Frameworks */, A9083E402DF2226F0042906E /* libz.tbd in Frameworks */,
A95FAA562DF4B62A00DE2F5A /* openssl.xcframework in Frameworks */, A95FAA562DF4B62A00DE2F5A /* openssl.xcframework in Frameworks */,
); );
@@ -166,6 +180,8 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
A92538C52DEE0742007E0A18 /* ContentView.swift */, A92538C52DEE0742007E0A18 /* ContentView.swift */,
A91AE3B12DF73E0900FF3537 /* TerminalView.swift */,
A91AE3BC2DF7402100FF3537 /* TextViewController.swift */,
A93143C52DF61FE300FCD5DB /* ViewModifiers.swift */, A93143C52DF61FE300FCD5DB /* ViewModifiers.swift */,
); );
path = Views; path = Views;
@@ -227,6 +243,11 @@
); );
name = ShhShell; name = ShhShell;
packageProductDependencies = ( packageProductDependencies = (
A91AE3892DF722A600FF3537 /* Runestone */,
A91AE3B42DF73F1D00FF3537 /* TreeSitterBash */,
A91AE3B62DF73F1D00FF3537 /* TreeSitterBashQueries */,
A91AE3B82DF73F1D00FF3537 /* TreeSitterBashRunestone */,
A91AE3BA2DF73F1D00FF3537 /* TreeSitterLanguagesCommon */,
); );
productName = ShhShell; productName = ShhShell;
productReference = A925389A2DEE06DC007E0A18 /* ShhShell.app */; productReference = A925389A2DEE06DC007E0A18 /* ShhShell.app */;
@@ -305,6 +326,8 @@
mainGroup = A92538912DEE06DC007E0A18; mainGroup = A92538912DEE06DC007E0A18;
minimizedProjectReferenceProxies = 1; minimizedProjectReferenceProxies = 1;
packageReferences = ( packageReferences = (
A91AE3882DF722A600FF3537 /* XCRemoteSwiftPackageReference "runestone" */,
A91AE3B32DF73F1D00FF3537 /* XCRemoteSwiftPackageReference "treesitterlanguages" */,
); );
preferredProjectObjectVersion = 77; preferredProjectObjectVersion = 77;
productRefGroup = A925389B2DEE06DC007E0A18 /* Products */; productRefGroup = A925389B2DEE06DC007E0A18 /* Products */;
@@ -353,6 +376,8 @@
A92538C82DEE0742007E0A18 /* ContentView.swift in Sources */, A92538C82DEE0742007E0A18 /* ContentView.swift in Sources */,
A93143C02DF61B3200FCD5DB /* Host.swift in Sources */, A93143C02DF61B3200FCD5DB /* Host.swift in Sources */,
A92538C92DEE0742007E0A18 /* ShhShellApp.swift in Sources */, A92538C92DEE0742007E0A18 /* ShhShellApp.swift in Sources */,
A91AE3B22DF73E0900FF3537 /* TerminalView.swift in Sources */,
A91AE3BD2DF7402100FF3537 /* TextViewController.swift in Sources */,
A9C897EF2DF1A9A400EF9A5F /* SSHHandler.swift in Sources */, A9C897EF2DF1A9A400EF9A5F /* SSHHandler.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@@ -687,6 +712,53 @@
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
/* End XCConfigurationList section */ /* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
A91AE3882DF722A600FF3537 /* XCRemoteSwiftPackageReference "runestone" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/simonbs/runestone";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.5.1;
};
};
A91AE3B32DF73F1D00FF3537 /* XCRemoteSwiftPackageReference "treesitterlanguages" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/simonbs/treesitterlanguages";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.1.10;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
A91AE3892DF722A600FF3537 /* Runestone */ = {
isa = XCSwiftPackageProductDependency;
package = A91AE3882DF722A600FF3537 /* XCRemoteSwiftPackageReference "runestone" */;
productName = Runestone;
};
A91AE3B42DF73F1D00FF3537 /* TreeSitterBash */ = {
isa = XCSwiftPackageProductDependency;
package = A91AE3B32DF73F1D00FF3537 /* XCRemoteSwiftPackageReference "treesitterlanguages" */;
productName = TreeSitterBash;
};
A91AE3B62DF73F1D00FF3537 /* TreeSitterBashQueries */ = {
isa = XCSwiftPackageProductDependency;
package = A91AE3B32DF73F1D00FF3537 /* XCRemoteSwiftPackageReference "treesitterlanguages" */;
productName = TreeSitterBashQueries;
};
A91AE3B82DF73F1D00FF3537 /* TreeSitterBashRunestone */ = {
isa = XCSwiftPackageProductDependency;
package = A91AE3B32DF73F1D00FF3537 /* XCRemoteSwiftPackageReference "treesitterlanguages" */;
productName = TreeSitterBashRunestone;
};
A91AE3BA2DF73F1D00FF3537 /* TreeSitterLanguagesCommon */ = {
isa = XCSwiftPackageProductDependency;
package = A91AE3B32DF73F1D00FF3537 /* XCRemoteSwiftPackageReference "treesitterlanguages" */;
productName = TreeSitterLanguagesCommon;
};
/* End XCSwiftPackageProductDependency section */
}; };
rootObject = A92538922DEE06DC007E0A18 /* Project object */; rootObject = A92538922DEE06DC007E0A18 /* Project object */;
} }

View File

@@ -0,0 +1,33 @@
{
"originHash" : "7b91b8af81dcd3e1958c781705a4b5920fdcdef24313a6e025be307b7bc092d5",
"pins" : [
{
"identity" : "runestone",
"kind" : "remoteSourceControl",
"location" : "https://github.com/simonbs/Runestone",
"state" : {
"revision" : "1fad339aab99cf2136ce6bf8c32da3265b2e85e5",
"version" : "0.5.1"
}
},
{
"identity" : "tree-sitter",
"kind" : "remoteSourceControl",
"location" : "https://github.com/tree-sitter/tree-sitter",
"state" : {
"revision" : "98be227227af10cc7a269cb3ffb23686c0610b17",
"version" : "0.20.9"
}
},
{
"identity" : "treesitterlanguages",
"kind" : "remoteSourceControl",
"location" : "https://github.com/simonbs/treesitterlanguages",
"state" : {
"revision" : "15cf3a9ec3ab95e0d058b7df9f35619123c9e02d",
"version" : "0.1.10"
}
}
],
"version" : 3
}

View File

@@ -16,6 +16,7 @@ class SSHHandler: ObservableObject {
@Published var authorized: Bool = false @Published var authorized: Bool = false
@Published var host: HostPr @Published var host: HostPr
@Published var terminal: String = ""
private let userDefaults = NSUbiquitousKeyValueStore.default private let userDefaults = NSUbiquitousKeyValueStore.default
private let logger = Logger(subsystem: "xy", category: "sshHandler") private let logger = Logger(subsystem: "xy", category: "sshHandler")
@@ -301,18 +302,18 @@ class SSHHandler: ObservableObject {
} }
} }
func readFromChannel() -> String? { func readFromChannel() {
guard ssh_channel_is_open(channel) != 0 else { return nil } guard ssh_channel_is_open(channel) != 0 else { return }
guard ssh_channel_is_eof(channel) == 0 else { return nil } guard ssh_channel_is_eof(channel) == 0 else { return }
var buffer: [CChar] = Array(repeating: 0, count: 256) var buffer: [CChar] = Array(repeating: 0, count: 256)
let nbytes = ssh_channel_read_nonblocking(channel, &buffer, UInt32(buffer.count), 0) let nbytes = ssh_channel_read_nonblocking(channel, &buffer, UInt32(buffer.count), 0)
guard nbytes > 0 else { return nil } guard nbytes > 0 else { return }
write(1, buffer, Int(nbytes)) write(1, buffer, Int(nbytes))
let data = Data(bytes: buffer, count: buffer.count) let data = Data(bytes: buffer, count: buffer.count)
return String(data: data, encoding: .utf8)! self.terminal.append(String(data: data, encoding: .utf8)!)
} }
private func logSshGetError() { private func logSshGetError() {

View File

@@ -12,8 +12,6 @@ struct ContentView: View {
@State var connected: Bool = false @State var connected: Bool = false
@State var testSucceded: Bool? @State var testSucceded: Bool?
@State var terminal: String = ""
var body: some View { var body: some View {
VStack { VStack {
Text(connected ? "connected" : "not connected") Text(connected ? "connected" : "not connected")
@@ -76,14 +74,13 @@ struct ContentView: View {
Button("request a shell") { Button("request a shell") {
handler.openShell() handler.openShell()
terminal.append(handler.readFromChannel() ?? "")
} }
Button("read from server") { Button("read from server") {
terminal.append(handler.readFromChannel() ?? "") handler.readFromChannel()
} }
Text(terminal) TerminalView(handler: handler)
} }
} }
} }

View File

@@ -0,0 +1,21 @@
//
// TerminalView.swift
// ShhShell
//
// Created by neon443 on 09/06/2025.
//
import SwiftUI
import Runestone
struct TerminalView: View {
@ObservedObject var handler: SSHHandler
var body: some View {
TextViewController(text: $handler.host.address)
}
}
#Preview {
TerminalView(handler: SSHHandler(host: debugHost()))
}

View File

@@ -0,0 +1,24 @@
//
// TextViewController.swift
// ShhShell
//
// Created by neon443 on 09/06/2025.
//
import Foundation
import UIKit
import SwiftUI
import Runestone
struct TextViewController: UIViewRepresentable {
@Binding var text: String
func makeUIView(context: Context) -> TextView {
var textView = TextView()
return textView
}
func updateUIView(_ textView: TextView, context: Context) {
textView.text = text
}
}