From daa02355016f95848a2ff21682e4878ada6dc90f Mon Sep 17 00:00:00 2001 From: Matt <85322+mattmassicotte@users.noreply.github.com> Date: Fri, 7 Oct 2022 07:47:32 -0400 Subject: [PATCH] Initial implemenation --- CODE_OF_CONDUCT.md | 133 ++++++++++++++++++++++ Package.resolved | 113 ++++++++++++++++++ Package.swift | 18 +++ README.md | 25 +++- Sources/ChimeRust/RustExtension.swift | 83 ++++++++++++++ Tests/ChimeRustTests/ChimeRustTests.swift | 7 ++ 6 files changed, 378 insertions(+), 1 deletion(-) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 Package.resolved create mode 100644 Package.swift create mode 100644 Sources/ChimeRust/RustExtension.swift create mode 100644 Tests/ChimeRustTests/ChimeRustTests.swift diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..907cbf1 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,133 @@ + +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +support@chimehq.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/Package.resolved b/Package.resolved new file mode 100644 index 0000000..ff7875a --- /dev/null +++ b/Package.resolved @@ -0,0 +1,113 @@ +{ + "pins" : [ + { + "identity" : "anycodable", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Flight-School/AnyCodable", + "state" : { + "revision" : "b1a7a8a6186f2fcb28f7bda67cfc545de48b3c80", + "version" : "0.6.2" + } + }, + { + "identity" : "chimekit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/ChimeKit", + "state" : { + "branch" : "main", + "revision" : "3dc4c8017f3e0e4ff31f10ba64250fb7229178aa" + } + }, + { + "identity" : "concurrencyplus", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/ConcurrencyPlus", + "state" : { + "revision" : "d603e3f8be17e71d93ec650fb31674b928b26e22", + "version" : "0.3.3" + } + }, + { + "identity" : "extendable", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/Extendable", + "state" : { + "revision" : "1e5f8b3b4e64fcfca4bfd5b0b38679cac7ea14c9", + "version" : "0.1.1" + } + }, + { + "identity" : "fseventswrapper", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Frizlab/FSEventsWrapper", + "state" : { + "revision" : "e0c59a2ce2775e5f6642da6d19207445f10112d0", + "version" : "1.0.2" + } + }, + { + "identity" : "glob", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Bouke/Glob", + "state" : { + "revision" : "deda6e163d2ff2a8d7e138e2c3326dbd71157faf", + "version" : "1.0.5" + } + }, + { + "identity" : "jsonrpc", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/JSONRPC", + "state" : { + "revision" : "55071da13d109e61584750f39c0941d49711b962", + "version" : "0.5.0" + } + }, + { + "identity" : "languageclient", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/LanguageClient", + "state" : { + "revision" : "f38654cb46d0d8fdc5cfab10d4d05bf4400ea7eb", + "version" : "0.2.6" + } + }, + { + "identity" : "languageserverprotocol", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/LanguageServerProtocol", + "state" : { + "revision" : "5f74d0574f0b56d36ed810b04322329527679219", + "version" : "0.7.8" + } + }, + { + "identity" : "operationplus", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/OperationPlus", + "state" : { + "revision" : "1340f95dce3e93d742497d88db18f8676f4badf4", + "version" : "1.6.0" + } + }, + { + "identity" : "processenv", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/ProcessEnv", + "state" : { + "revision" : "7bcb6c11593be08456f48042fad1a7bf875f217a", + "version" : "0.3.0" + } + }, + { + "identity" : "processservice", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/ProcessService", + "state" : { + "revision" : "8481508879714dafeb1c460c93aee180430ada35", + "version" : "0.1.2" + } + } + ], + "version" : 2 +} diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..228e758 --- /dev/null +++ b/Package.swift @@ -0,0 +1,18 @@ +// swift-tools-version: 5.6 + +import PackageDescription + +let package = Package( + name: "chime-rust", + platforms: [.macOS(.v11)], + products: [ + .library(name: "ChimeRust", targets: ["ChimeRust"]), + ], + dependencies: [ + .package(url: "https://github.com/ChimeHQ/ChimeKit", branch: "main"), + ], + targets: [ + .target(name: "ChimeRust", dependencies: ["ChimeKit"]), + .testTarget(name: "ChimeRustTests", dependencies: ["ChimeRust"]), + ] +) diff --git a/README.md b/README.md index bf1da1d..3ff37b2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,25 @@ +[![License][license badge]][license] + # chime-rust -A Chime extension for Rust +A [Chime][chime] extension for Rust. + +## Overview + +This Chime extension supports the [Rust][rust] programming language. It integrates [rust-analyzer][rust-analyzer] with [ChimeKit][chimekit]'s `ExtensionProtocol`. + +## Installation + +chime-rust's core functionality is built directly into Chime 2.0. + +## Suggestions or Feedback + +We'd love to hear from you! Get in touch via [twitter](https://twitter.com/chimehq), an issue, or a pull request. + +Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms. + +[license]: https://opensource.org/licenses/BSD-3-Clause +[license badge]: https://img.shields.io/github/license/ChimeHQ/chime-rust +[chime]: https://www.chimehq.com +[rust]: https://www.rust-lang.org +[rust-analyzer]: https://rust-analyzer.github.io +[chimekit]: https://github.com/ChimeHQ/ChimeKit diff --git a/Sources/ChimeRust/RustExtension.swift b/Sources/ChimeRust/RustExtension.swift new file mode 100644 index 0000000..ba5224d --- /dev/null +++ b/Sources/ChimeRust/RustExtension.swift @@ -0,0 +1,83 @@ +import Foundation +import os.log + +import ChimeKit +import ProcessServiceClient + +public final class RustExtension { + private static let processHostService: String = "com.chimehq.ChimeKit.ProcessService" + + let host: any HostProtocol + private let lspService: LSPService + private let logger: Logger + + public init(host: any HostProtocol) { + self.host = host + self.logger = Logger(subsystem: "com.chimehq.ChimeRust", category: "RustExtension") + + let filter = LSPService.contextFilter(for: [.rustSource], projectFiles: ["Cargo.toml"]) + + self.lspService = LSPService(host: host, + contextFilter: filter, + executionParamsProvider: RustExtension.provideParams, + processHostServiceName: nil) + } +} + +extension RustExtension { + private static func provideParams() async throws -> Process.ExecutionParameters { + let userEnv = try await HostedProcess.userEnvironment(with: RustExtension.processHostService) + + let whichParams = Process.ExecutionParameters(path: "/usr/bin/which", arguments: ["rust-analyzer"], environment: userEnv) + + let whichProcess = HostedProcess(named: RustExtension.processHostService, parameters: whichParams) + + let data = try await whichProcess.runAndReadStdout() + + guard let output = String(data: data, encoding: .utf8) else { + throw LSPServiceError.serverNotFound + } + + if output.isEmpty { + throw LSPServiceError.serverNotFound + } + + let path = output.trimmingCharacters(in: .whitespacesAndNewlines) + + print("found analyzer at: ", path) + + return .init(path: path, environment: userEnv) + } +} + +extension RustExtension: ExtensionProtocol { + public func didOpenProject(with context: ProjectContext) async throws { + try await lspService.didOpenProject(with: context) + } + + public func willCloseProject(with context: ProjectContext) async throws { + try await lspService.willCloseProject(with: context) + } + + public func symbolService(for context: ProjectContext) async throws -> SymbolQueryService? { + return try await lspService.symbolService(for: context) + } + + public func didOpenDocument(with context: DocumentContext) async throws -> URL? { + return try await lspService.didOpenDocument(with: context) + } + + public func didChangeDocumentContext(from oldContext: DocumentContext, to newContext: DocumentContext) async throws { + return try await lspService.didChangeDocumentContext(from: oldContext, to: newContext) + } + + public func willCloseDocument(with context: DocumentContext) async throws { + return try await lspService.willCloseDocument(with: context) + } + + public func documentService(for context: DocumentContext) async throws -> DocumentService? { + return try await lspService.documentService(for: context) + } +} + + diff --git a/Tests/ChimeRustTests/ChimeRustTests.swift b/Tests/ChimeRustTests/ChimeRustTests.swift new file mode 100644 index 0000000..56c0d3e --- /dev/null +++ b/Tests/ChimeRustTests/ChimeRustTests.swift @@ -0,0 +1,7 @@ +import XCTest +@testable import ChimeRust + +final class ChimeRustTests: XCTestCase { + func testExample() throws { + } +}