From f909b20c540ea99dddfd04b8439ee35b8dd703b8 Mon Sep 17 00:00:00 2001 From: Akshay Date: Wed, 27 Oct 2021 17:10:42 +0530 Subject: allow stdin input to statix-single, vim plugin --- bin/Cargo.toml | 2 +- bin/src/config.rs | 4 ++-- bin/src/fix/single.rs | 23 +++++++++-------------- bin/src/main.rs | 25 +++++++++++++++++++------ flake.nix | 11 +++++++++-- lib/src/lib.rs | 7 +++++++ vim-plugin/ftplugin/nix.vim | 8 ++++++++ vim-plugin/plugin/statix.vim | 14 ++++++++++++++ 8 files changed, 69 insertions(+), 25 deletions(-) create mode 100644 vim-plugin/ftplugin/nix.vim create mode 100644 vim-plugin/plugin/statix.vim diff --git a/bin/Cargo.toml b/bin/Cargo.toml index 481217a..971fb47 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "statix" -version = "0.2.0" +version = "0.2.2" edition = "2018" license = "MIT" diff --git a/bin/src/config.rs b/bin/src/config.rs index c856a59..79bed35 100644 --- a/bin/src/config.rs +++ b/bin/src/config.rs @@ -77,8 +77,8 @@ impl Fix { #[derive(Clap, Debug)] pub struct Single { /// File to run single-fix on - #[clap(default_value = ".", parse(from_os_str))] - pub target: PathBuf, + #[clap(parse(from_os_str))] + pub target: Option, /// Position to attempt a fix at #[clap(short, long, parse(try_from_str = parse_line_col))] diff --git a/bin/src/fix/single.rs b/bin/src/fix/single.rs index c09c710..4d492f8 100644 --- a/bin/src/fix/single.rs +++ b/bin/src/fix/single.rs @@ -15,7 +15,7 @@ fn pos_to_byte(line: usize, col: usize, src: &str) -> Result Result Result { - let offset = offset - TextSize::from(1u32); // we don't really need the source to form a completely parsed tree let parsed = rnix::parse(src); @@ -38,22 +37,18 @@ fn find(offset: TextSize, src: &str) -> Result { .preorder_with_tokens() .filter_map(|event| match event { WalkEvent::Enter(child) => { - if child.text_range().start() == offset { - LINTS.get(&child.kind()).map(|rules| { - rules - .iter() - .filter_map(|rule| rule.validate(&child)) - .filter(|report| report.total_suggestion_range().is_some()) - .next() - }) - } else { - None - } + LINTS.get(&child.kind()).map(|rules| { + rules + .iter() + .filter_map(|rule| rule.validate(&child)) + .filter(|report| report.total_suggestion_range().is_some()) + .next() + }) } _ => None, }) .flatten() - .next() + .find(|report| report.total_diagnostic_range().unwrap().contains(offset)) .ok_or(SingleFixErr::NoOp) } diff --git a/bin/src/main.rs b/bin/src/main.rs index 4063621..9e9c8ac 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -4,7 +4,7 @@ mod fix; mod lint; mod traits; -use std::io; +use std::io::{self, BufRead}; use crate::{ err::{FixErr, SingleFixErr, StatixErr}, @@ -55,15 +55,26 @@ fn _main() -> Result<(), StatixErr> { } } } + // FIXME: this block nasty, configure in/out streams in `impl Single` maybe SubCommand::Single(single_config) => { - let path = single_config.target; - let src = std::fs::read_to_string(&path).map_err(SingleFixErr::InvalidPath)?; + let src = if let Some(path) = &single_config.target { + std::fs::read_to_string(&path).map_err(SingleFixErr::InvalidPath)? + } else { + io::stdin().lock().lines().map(|l| l.unwrap()).collect::>().join("\n") + }; + + let path_id = if let Some(path) = &single_config.target { + path.display().to_string() + } else { + "".to_owned() + }; + let (line, col) = single_config.position; let single_fix_result = fix::single(line, col, &src)?; if single_config.diff_only { let text_diff = TextDiff::from_lines(src.as_str(), &single_fix_result.src); - let old_file = format!("{}", path.display()); - let new_file = format!("{} [fixed]", path.display()); + let old_file = format!("{}", path_id); + let new_file = format!("{} [fixed]", path_id); println!( "{}", text_diff @@ -71,9 +82,11 @@ fn _main() -> Result<(), StatixErr> { .context_radius(4) .header(&old_file, &new_file) ); - } else { + } else if let Some(path) = single_config.target { std::fs::write(&path, &*single_fix_result.src) .map_err(SingleFixErr::InvalidPath)?; + } else { + print!("{}", &*single_fix_result.src) } } } diff --git a/flake.nix b/flake.nix index ba1c431..26190aa 100644 --- a/flake.nix +++ b/flake.nix @@ -49,7 +49,7 @@ statix = with final; pkgs.stdenv.mkDerivation { pname = "statix"; - version = "v0.2.0"; + version = "v0.2.2"; src = builtins.path { path = ./.; name = "statix"; @@ -75,10 +75,17 @@ }; }; + statix-vim = + with final; pkgs.vimUtils.buildVimPlugin { + pname = "statix-vim"; + version = "0.1.0"; + src = ./vim-plugin; + }; + }; packages = forAllSystems (system: { - inherit (nixpkgsFor."${system}") statix; + inherit (nixpkgsFor."${system}") statix statix-vim; }); defaultPackage = diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 41e38c8..c2f24c6 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -56,6 +56,13 @@ impl Report { .flat_map(|d| Some(d.suggestion.as_ref()?.at)) .reduce(|acc, next| acc.cover(next)) } + /// A range that encompasses all the diagnostics provided in this report + pub fn total_diagnostic_range(&self) -> Option { + self.diagnostics + .iter() + .flat_map(|d| Some(d.at)) + .reduce(|acc, next| acc.cover(next)) + } /// Unsafe but handy replacement for above pub fn range(&self) -> TextRange { self.total_suggestion_range().unwrap() diff --git a/vim-plugin/ftplugin/nix.vim b/vim-plugin/ftplugin/nix.vim new file mode 100644 index 0000000..885857f --- /dev/null +++ b/vim-plugin/ftplugin/nix.vim @@ -0,0 +1,8 @@ +setlocal makeprg=statix\ check\ -o\ errfmt\ % +setlocal errorformat=%f>%l:%c:%t:%n:%m + +augroup StatixCheck + autocmd! + autocmd! BufWritePost *.nix | silent make! | silent redraw! + autocmd QuickFixCmdPost [^l]* cwindow +augroup END diff --git a/vim-plugin/plugin/statix.vim b/vim-plugin/plugin/statix.vim new file mode 100644 index 0000000..736cce2 --- /dev/null +++ b/vim-plugin/plugin/statix.vim @@ -0,0 +1,14 @@ +function! ApplyStatixSuggestion() + let l:l = line('.') + let l:c = col('.') + let l:filter = "%!statix single -p " . l . "," . c . "" + execute l:filter + + silent if v:shell_error == 1 + undo + endif + + call cursor(l, c) +endfunction + +nnoremap gf :call ApplyStatixSuggestion() -- cgit v1.2.3