10000 cli: ace editor integration (#714) · rune-rs/rune@e36fcc3 · GitHub
[go: up one dir, main page]

Skip to content

Commit e36fcc3

Browse files
authored
cli: ace editor integration (#714)
1 parent ddccb1e commit e36fcc3

File tree

11 files changed

+607
-4
lines changed

11 files changed

+607
-4
lines changed

crates/rune/src/cli/ace.rs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
use std::io::Write;
2+
use std::path::PathBuf;
3+
4+
use crate::doc::Artifacts;
5+
6+
use anyhow::{Context, Result};
7+
use clap::Parser;
8+
9+
use crate::alloc::prelude::*;
10+
use crate::alloc::Vec;
11+
use crate::cli::naming::Naming;
12+
use crate::cli::{AssetKind, CommandBase, Config, Entry, EntryPoint, ExitCode, Io, SharedFlags};
13+
use crate::compile::FileSourceLoader;
14+
use crate::{Diagnostics, Options, Source, Sources};
15+
16+
#[derive(Parser, Debug)]
17+
pub(super) struct Flags {
18+
/// Exit with a non-zero exit-code even for warnings
19+
#[arg(long)]
20+
warnings_are_errors: bool,
21+
/// Output directory to write documentation to.
22+
#[arg(long)]
23+
output: Option<PathBuf>,
24+
/// Generate .await and ? extension for functions.
25+
#[arg(long)]
26+
extensions: bool,
27+
}
28+
29+
impl CommandBase for Flags {
30+
#[inline]
31+
fn is_workspace(&self, _: AssetKind) -> bool {
32+
true
33+
}
34+
35+
#[inline]
36+
fn describe(&self) -> &str {
37+
"Documenting"
38+
}
39+
}
40+
41+
pub(super) fn run<'p, I>(
42+
io: &mut Io<'_>,
43+
entry: &mut Entry<'_>,
44+
c: &Config,
45+
flags: &Flags,
46+
shared: &SharedFlags,
47+
options: &Options,
48+
entries: I,
49+
) -> Result<ExitCode>
50+
where
51+
I: IntoIterator<Item = EntryPoint<'p>>,
52+
{
53+
let root = match &flags.output {
54+
Some(root) => root.clone(),
55+
None => match &c.manifest_root {
56+
Some(path) => path.join("target").join("rune-ace"),
57+
None => match std::env::var_os("CARGO_TARGET_DIR") {
58+
Some(target) => {
59+
let mut target = PathBuf::from(target);
60+
target.push("rune-ace");
61+
target
62+
}
63+
None => {
64+
let mut target = PathBuf::new();
65+
target.push("target");
66+
target.push("rune-ace");
67+
target
68+
}
69+
},
70+
},
71+
};
72+
73+
writeln!(io.stdout, "Building ace autocompletion: {}", root.display())?;
74+
75+
let context = shared.context(entry, c, None)?;
76+
77+
let mut visitors = Vec::new();
78+
79+
let mut naming = Naming::default();
80+
81+
for e in entries {
82+
let item = naming.item(&e)?;
83+
84+
let mut visitor = crate::doc::Visitor::new(&item)?;
85+
let mut sources = Sources::new();
86+
87+
let source = match Source::from_path(e.path()) {
88+
Ok(source) => source,
89+
Err(error) => return Err(error).context(e.path().display().try_to_string()?),
90+
};
91+
92+
sources.insert(source)?;
93+
94+
let mut diagnostics = if shared.warnings || flags.warnings_are_errors {
95+
Diagnostics::new()
96+
} else {
97+
Diagnostics::without_warnings()
98+
};
99+
100+
let mut source_loader = FileSourceLoader::new();
101+
102+
let _ = crate::prepare(&mut sources)
103+
.with_context(&context)
104+
.with_diagnostics(&mut diagnostics)
105+
.with_options(options)
106+
.with_visitor(&mut visitor)?
107+
.with_source_loader(&mut source_loader)
108+
.build();
109+
110+
diagnostics.emit(&mut io.stdout.lock(), &sources)?;
111+
112+
if diagnostics.has_error() || flags.warnings_are_errors && diagnostics.has_warning() {
113+
return Ok(ExitCode::Failure);
114+
}
115+
116+
visitors.try_push(visitor)?;
117+
}
118+
119+
let mut artifacts = Artifacts::new();
120+
crate::doc::build_autocomplete(&mut artifacts, &context, &visitors, flags.extensions)?;
121+
122+
for asset in artifacts.assets() {
123+
asset.build(&root)?;
124+
}
125+
126+
Ok(ExitCode::Success)
127+
}

crates/rune/src/cli/mod.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//! * Build a language server, which is aware of things only available in your
77
//! context.
88
9+
mod ace;
910
mod benches;
1011
mod check;
1112
mod doc;
@@ -431,6 +432,8 @@ enum Command {
431432
Check(CommandShared<check::Flags>),
432433
/// Build documentation.
433434
Doc(CommandShared<doc::Flags>),
435+
/// Build ace autocompletion.
436+
Ace(CommandShared<ace::Flags>),
434437
/// Run all tests but do not execute
435438
Test(CommandShared<tests::Flags>),
436439
/// Run the given program as a benchmark
@@ -446,9 +449,10 @@ enum Command {
446449
}
447450

448451
impl Command {
449-
const ALL: [&'static str; 8] = [
452+
const ALL: [&'static str; 9] = [
450453
"check",
451454
"doc",
455+
"ace",
452456
"test",
453457
"bench",
454458
"run",
@@ -461,6 +465,7 @@ impl Command {
461465
let (shared, command): (_, &mut dyn CommandBase) = match self {
462466
Command::Check(shared) => (&mut shared.shared, &mut shared.command),
463467
Command::Doc(shared) => (&mut shared.shared, &mut shared.command),
468+
Command::Ace(shared) => (&mut shared.shared, &mut shared.command),
464469
Command::Test(shared) => (&mut shared.shared, &mut shared.command),
465470
Command::Bench(shared) => (&mut shared.shared, &mut shared.command),
466471
Command::Run(shared) => (&mut shared.shared, &mut shared.command),
@@ -476,6 +481,7 @@ impl Command {
476481
let (shared, command): (_, &dyn CommandBase) = match self {
477482
Command::Check(shared) => (&shared.shared, &shared.command),
478483
Command::Doc(shared) => (&shared.shared, &shared.command),
484+
Command::Ace(shared) => (&shared.shared, &shared.command),
479485
Command::Test(shared) => (&shared.shared, &shared.command),
480486
Command::Bench(shared) => (&shared.shared, &shared.command),
481487
Command::Run(shared) => (&shared.shared, &shared.command),
@@ -911,6 +917,10 @@ where
911917
let options = f.options()?;
912918
return doc::run(io, entry, c, &f.command, &f.shared, &options, entries);
913919
}
920+
Command::Ace(f) => {
921+
let options = f.options()?;
922+
return ace::run(io, entry, c, &f.command, &f.shared, &options, entries);
923+
}
914924
Command::Fmt(f) => {
915925
let options = f.options()?;
916926
return format::run(io, entry, c, entries, &f.command, &f.shared, &options);

crates/rune/src/compile/prelude.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use core::ops::Deref;
2+
13
use crate::alloc::{self, Box, HashMap};
24
use crate::item::{IntoComponent, Item, ItemBuf};
35

@@ -54,6 +56,15 @@ impl Prelude {
5456
Some(self.prelude.get(name)?)
5557
}
5658

59+
/// Return the local name of an item
60+
#[allow(dead_code)]
61+
pub(crate) fn get_local<'a>(&'a self, item: &ItemBuf) -> Option<&'a str> {
62+
self.prelude
63+
.iter()
64+
.find(|(_, i)| i == &item)
65+
.map(|(s, _)| s.deref())
66+
}
67+
5768
/// Define a prelude item.
5869
fn add_prelude<I>(&mut self, local: &str, path: I) -> alloc::Result<()>
5970
where

0 commit comments

Comments
 (0)
0