Skip to content
This repository has been archived by the owner on Oct 24, 2023. It is now read-only.

chore: extract out src/nu.rs; add tests #4

Merged
merged 1 commit into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 3 additions & 45 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
#![deny(clippy::all, unsafe_code)]

use std::borrow::Cow;
use std::path::PathBuf;

use serde::Deserialize;
use nu::{convert_position, IdeComplete, IdeGotoDef, IdeHover};
use serde_json::Value;
use tower_lsp::jsonrpc::Result;
use tower_lsp::lsp_types::*;
use tower_lsp::{Client, LanguageServer, LspService, Server};

mod nu;

#[derive(Debug)]
struct Backend {
client: Client,
Expand Down Expand Up @@ -211,49 +212,6 @@ impl LanguageServer for Backend {
}
}

#[derive(Deserialize)]
struct IdeComplete {
completions: Vec<String>,
}

#[derive(Deserialize)]
struct IdeGotoDef {
// end: usize,
file: PathBuf,
// start: usize,
}

#[derive(Deserialize)]
struct IdeHover {
hover: String,
// span: Option<Range>,
}

// ported from https://github.com/nushell/vscode-nushell-lang
fn convert_position(position: &Position, text: &str) -> usize {
let mut line = 0;
let mut character = 0;
let buffer = text.as_bytes();

let mut i = 0;
while i < buffer.len() {
if line == position.line && character == position.character {
return i;
}

if buffer[i] == 0x0a {
line += 1;
character = 0;
} else {
character += 1;
}

i += 1;
}

i
}

#[tokio::main]
async fn main() {
let stdin = tokio::io::stdin();
Expand Down
103 changes: 103 additions & 0 deletions src/nu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use std::path::PathBuf;

use serde::Deserialize;
use tower_lsp::lsp_types::Position;

#[derive(Deserialize)]
pub(crate) struct IdeComplete {
pub completions: Vec<String>,
}

#[derive(Deserialize)]
pub(crate) struct IdeGotoDef {
// end: usize,
pub file: PathBuf,
// start: usize,
}

#[derive(Deserialize)]
pub(crate) struct IdeHover {
pub hover: String,
// span: Option<Range>,
}

// ported from https://github.com/nushell/vscode-nushell-lang
pub(crate) fn convert_position(position: &Position, text: &str) -> usize {
let mut line = 0;
let mut character = 0;
let buffer = text.as_bytes();

let mut i = 0;
while i < buffer.len() {
if line == position.line && character == position.character {
return i;
}

if buffer[i] == 0x0a {
line += 1;
character = 0;
} else {
character += 1;
}

i += 1;
}

i
}

// ported from https://github.com/nushell/vscode-nushell-lang
#[allow(dead_code)]
pub(crate) fn convert_span() -> Position {
todo!()
}

// ported from https://github.com/nushell/vscode-nushell-lang
#[allow(dead_code)]
pub(crate) fn find_line_breaks(text: &str) -> Vec<usize> {
text.as_bytes()
.iter()
.enumerate()
.filter_map(|(i, b)| if b == &0x0a { Some(i) } else { None })
.collect()
}

// ported from https://github.com/nushell/vscode-nushell-lang
#[allow(dead_code)]
pub(crate) fn lower_bound_binary_search(_offset: usize, _line_breaks: &[usize]) -> Position {
Position::default()
}

#[cfg(test)]
mod tests {
use super::*;

static FIXTURE: &str = "
#! /usr/bin/env nu
def main [] {
ls | sort-by 'size' | first
}
";

#[test]
fn convert_position_ok() {
assert_eq!(convert_position(&Position::default(), FIXTURE.trim()), 0);

// `ls | ...`
assert_eq!(
convert_position(
&Position {
line: 2,
character: 4
},
FIXTURE.trim()
),
37
);
}

#[test]
fn find_line_breaks_ok() {
assert_eq!(find_line_breaks(FIXTURE.trim()), vec![18, 32, 64]);
}
}