Skip to content

Commit

Permalink
minor cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
ul committed Jan 2, 2019
1 parent 4dde26b commit 6d23cfa
Show file tree
Hide file tree
Showing 6 changed files with 384 additions and 359 deletions.
58 changes: 58 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use serde::Deserialize;
use std::collections::HashMap;
use toml;
use tree_sitter::Node;

#[derive(Deserialize, Default)]
pub struct Config {
#[serde(default)]
filetype: HashMap<String, FiletypeConfig>,
}

#[derive(Clone, Deserialize, Default)]
pub struct FiletypeConfig {
blacklist: Option<Vec<String>>,
whitelist: Option<Vec<String>>,
#[serde(default)]
group: HashMap<String, Vec<String>>,
}

impl Config {
pub fn load<P: AsRef<std::path::Path>>(path: P) -> Option<Self> {
let config = std::fs::read_to_string(path).ok()?;
let mut config: Config = toml::from_str(&config).ok()?;
if config.filetype.get("default").is_none() {
config
.filetype
.insert("default".to_owned(), FiletypeConfig::default());
}
Some(config)
}

pub fn get_filetype_config<'a>(&'a self, filetype: &str) -> &'a FiletypeConfig {
self.filetype
.get(filetype)
.or_else(|| self.filetype.get("default"))
.unwrap()
}
}

impl FiletypeConfig {
pub fn is_node_visible(&self, node: Node) -> bool {
let kind = node.kind();
match &self.whitelist {
Some(whitelist) => whitelist.iter().any(|x| x == kind),
None => match &self.blacklist {
Some(blacklist) => !blacklist.iter().any(|x| x == kind),
None => true,
},
}
}

pub fn resolve_alias<'a>(&'a self, kind: &str) -> Vec<String> {
self.group
.get(kind)
.cloned()
.unwrap_or_else(|| vec![kind.to_string()])
}
}
87 changes: 87 additions & 0 deletions src/ffi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
use tree_sitter::Language;

extern "C" {
#[cfg(feature = "bash")]
fn tree_sitter_bash() -> Language;
#[cfg(feature = "c")]
fn tree_sitter_c() -> Language;
#[cfg(feature = "c_sharp")]
fn tree_sitter_c_sharp() -> Language;
#[cfg(feature = "cpp")]
fn tree_sitter_cpp() -> Language;
#[cfg(feature = "css")]
fn tree_sitter_css() -> Language;
#[cfg(feature = "go")]
fn tree_sitter_go() -> Language;
#[cfg(feature = "haskell")]
fn tree_sitter_haskell() -> Language;
#[cfg(feature = "html")]
fn tree_sitter_html() -> Language;
#[cfg(feature = "java")]
fn tree_sitter_java() -> Language;
#[cfg(feature = "javascript")]
fn tree_sitter_javascript() -> Language;
#[cfg(feature = "json")]
fn tree_sitter_json() -> Language;
#[cfg(feature = "julia")]
fn tree_sitter_julia() -> Language;
#[cfg(feature = "ocaml")]
fn tree_sitter_ocaml() -> Language;
#[cfg(feature = "php")]
fn tree_sitter_php() -> Language;
#[cfg(feature = "python")]
fn tree_sitter_python() -> Language;
#[cfg(feature = "ruby")]
fn tree_sitter_ruby() -> Language;
#[cfg(feature = "rust")]
fn tree_sitter_rust() -> Language;
#[cfg(feature = "scala")]
fn tree_sitter_scala() -> Language;
#[cfg(feature = "typescript")]
fn tree_sitter_typescript() -> Language;
}

pub fn filetype_to_language(filetype: &str) -> Option<Language> {
let sitter = match filetype {
#[cfg(feature = "bash")]
"sh" => tree_sitter_bash,
#[cfg(feature = "c")]
"c" => tree_sitter_c,
#[cfg(feature = "c_sharp")]
"c_sharp" => tree_sitter_c_sharp,
#[cfg(feature = "cpp")]
"cpp" => tree_sitter_cpp,
#[cfg(feature = "css")]
"css" => tree_sitter_css,
#[cfg(feature = "go")]
"go" => tree_sitter_go,
#[cfg(feature = "haskell")]
"haskell" => tree_sitter_haskell,
#[cfg(feature = "html")]
"html" => tree_sitter_html,
#[cfg(feature = "java")]
"java" => tree_sitter_java,
#[cfg(feature = "javascript")]
"javascript" => tree_sitter_javascript,
#[cfg(feature = "json")]
"json" => tree_sitter_json,
#[cfg(feature = "julia")]
"julia" => tree_sitter_julia,
#[cfg(feature = "ocaml")]
"ocaml" => tree_sitter_ocaml,
#[cfg(feature = "php")]
"php" => tree_sitter_php,
#[cfg(feature = "python")]
"python" => tree_sitter_python,
#[cfg(feature = "ruby")]
"ruby" => tree_sitter_ruby,
#[cfg(feature = "rust")]
"rust" => tree_sitter_rust,
#[cfg(feature = "scala")]
"scala" => tree_sitter_scala,
#[cfg(feature = "typescript")]
"typescript" => tree_sitter_typescript,
_ => return None,
};
Some(unsafe { sitter() })
}
89 changes: 89 additions & 0 deletions src/kakoune.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use itertools::Itertools;
use tree_sitter::{Point, Range};

pub fn select_ranges(buffer: &[String], ranges: &[Range]) -> String {
if ranges.is_empty() {
"fail no selections remaining".into()
} else {
format!("select {}", ranges_to_selections_desc(&buffer, &ranges))
}
}

pub fn ranges_to_selections_desc(buffer: &[String], ranges: &[Range]) -> String {
ranges
.iter()
.map(|range| {
let mut end_row = range.end_point.row;
let mut end_column = range.end_point.column;
if end_column > 0 {
end_column -= 1;
} else {
end_row -= 1;
end_column = 1_000_000;
}
format!(
"{},{}",
point_to_kak_coords(buffer, range.start_point),
point_to_kak_coords(buffer, Point::new(end_row, end_column))
)
})
.join(" ")
}

pub fn selections_desc_to_ranges(buffer: &[String], selections_desc: &str) -> Vec<Range> {
selections_desc
.split_whitespace()
.map(|selection_desc| selection_desc_to_range(buffer, selection_desc))
.collect()
}

fn selection_desc_to_range(buffer: &[String], selection_desc: &str) -> Range {
let mut range = selection_desc.split(',');
let start = range.next().unwrap();
let end = range.next().unwrap();
let (start_byte, start_point) = kak_coords_to_byte_and_point(buffer, start);
let (end_byte, end_point) = kak_coords_to_byte_and_point(buffer, end);
let reverse = start_byte > end_byte;
if reverse {
Range {
start_byte: end_byte,
end_byte: start_byte,
start_point: end_point,
end_point: start_point,
}
} else {
Range {
start_byte,
end_byte,
start_point,
end_point,
}
}
}

fn point_to_kak_coords(buffer: &[String], p: Point) -> String {
let offset = buffer[p.row]
.char_indices()
.enumerate()
.find_map(|(column, (offset, _))| {
if column == p.column {
Some(offset)
} else {
None
}
})
.unwrap_or_else(|| buffer[p.row].len());
format!("{}.{}", p.row + 1, offset + 1)
}

fn kak_coords_to_byte_and_point(buffer: &[String], coords: &str) -> (usize, Point) {
let mut coords = coords.split('.');
let row = coords.next().unwrap().parse::<usize>().unwrap() - 1;
let offset = coords.next().unwrap().parse::<usize>().unwrap() - 1;
let byte = buffer[..row].iter().fold(0, |offset, c| offset + c.len()) + offset;
let column = buffer[row]
.char_indices()
.position(|(i, _)| i == offset)
.unwrap();
(byte, Point::new(row, column))
}
19 changes: 19 additions & 0 deletions src/log.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use sloggers::terminal::{Destination, TerminalLoggerBuilder};
use sloggers::types::Severity;
use sloggers::Build;

pub fn init_global_logger(verbosity: u8) {
let level = match verbosity {
0 => Severity::Error,
1 => Severity::Warning,
2 => Severity::Info,
3 => Severity::Debug,
_ => Severity::Trace,
};

let mut builder = TerminalLoggerBuilder::new();
builder.level(level);
builder.destination(Destination::Stderr);
let logger = builder.build().unwrap();
let _guard = slog_scope::set_global_logger(logger);
}
Loading

0 comments on commit 6d23cfa

Please sign in to comment.