Lints and suggestions for the Nix programming language
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

allow stdin input to statix-single, vim plugin

Akshay f909b20c ed1ee66b

+69 -25
+1 -1
bin/Cargo.toml
··· 1 1 [package] 2 2 name = "statix" 3 - version = "0.2.0" 3 + version = "0.2.2" 4 4 edition = "2018" 5 5 license = "MIT" 6 6
+2 -2
bin/src/config.rs
··· 77 77 #[derive(Clap, Debug)] 78 78 pub struct Single { 79 79 /// File to run single-fix on 80 - #[clap(default_value = ".", parse(from_os_str))] 81 - pub target: PathBuf, 80 + #[clap(parse(from_os_str))] 81 + pub target: Option<PathBuf>, 82 82 83 83 /// Position to attempt a fix at 84 84 #[clap(short, long, parse(try_from_str = parse_line_col))]
+9 -14
bin/src/fix/single.rs
··· 15 15 for (l, _) in src 16 16 .split_inclusive('\n') 17 17 .zip(1..) 18 - .take_while(|(_, i)| i < &line) 18 + .take_while(|(_, i)| *i < line) 19 19 { 20 20 byte += TextSize::of(l); 21 21 } ··· 29 29 } 30 30 31 31 fn find(offset: TextSize, src: &str) -> Result<Report, SingleFixErr> { 32 - let offset = offset - TextSize::from(1u32); 33 32 // we don't really need the source to form a completely parsed tree 34 33 let parsed = rnix::parse(src); 35 34 ··· 38 37 .preorder_with_tokens() 39 38 .filter_map(|event| match event { 40 39 WalkEvent::Enter(child) => { 41 - if child.text_range().start() == offset { 42 - LINTS.get(&child.kind()).map(|rules| { 43 - rules 44 - .iter() 45 - .filter_map(|rule| rule.validate(&child)) 46 - .filter(|report| report.total_suggestion_range().is_some()) 47 - .next() 48 - }) 49 - } else { 50 - None 51 - } 40 + LINTS.get(&child.kind()).map(|rules| { 41 + rules 42 + .iter() 43 + .filter_map(|rule| rule.validate(&child)) 44 + .filter(|report| report.total_suggestion_range().is_some()) 45 + .next() 46 + }) 52 47 } 53 48 _ => None, 54 49 }) 55 50 .flatten() 56 - .next() 51 + .find(|report| report.total_diagnostic_range().unwrap().contains(offset)) 57 52 .ok_or(SingleFixErr::NoOp) 58 53 } 59 54
+19 -6
bin/src/main.rs
··· 4 4 mod lint; 5 5 mod traits; 6 6 7 - use std::io; 7 + use std::io::{self, BufRead}; 8 8 9 9 use crate::{ 10 10 err::{FixErr, SingleFixErr, StatixErr}, ··· 55 55 } 56 56 } 57 57 } 58 + // FIXME: this block nasty, configure in/out streams in `impl Single` maybe 58 59 SubCommand::Single(single_config) => { 59 - let path = single_config.target; 60 - let src = std::fs::read_to_string(&path).map_err(SingleFixErr::InvalidPath)?; 60 + let src = if let Some(path) = &single_config.target { 61 + std::fs::read_to_string(&path).map_err(SingleFixErr::InvalidPath)? 62 + } else { 63 + io::stdin().lock().lines().map(|l| l.unwrap()).collect::<Vec<String>>().join("\n") 64 + }; 65 + 66 + let path_id = if let Some(path) = &single_config.target { 67 + path.display().to_string() 68 + } else { 69 + "<unknown>".to_owned() 70 + }; 71 + 61 72 let (line, col) = single_config.position; 62 73 let single_fix_result = fix::single(line, col, &src)?; 63 74 if single_config.diff_only { 64 75 let text_diff = TextDiff::from_lines(src.as_str(), &single_fix_result.src); 65 - let old_file = format!("{}", path.display()); 66 - let new_file = format!("{} [fixed]", path.display()); 76 + let old_file = format!("{}", path_id); 77 + let new_file = format!("{} [fixed]", path_id); 67 78 println!( 68 79 "{}", 69 80 text_diff ··· 71 82 .context_radius(4) 72 83 .header(&old_file, &new_file) 73 84 ); 74 - } else { 85 + } else if let Some(path) = single_config.target { 75 86 std::fs::write(&path, &*single_fix_result.src) 76 87 .map_err(SingleFixErr::InvalidPath)?; 88 + } else { 89 + print!("{}", &*single_fix_result.src) 77 90 } 78 91 } 79 92 }
+9 -2
flake.nix
··· 49 49 50 50 statix = with final; pkgs.stdenv.mkDerivation { 51 51 pname = "statix"; 52 - version = "v0.2.0"; 52 + version = "v0.2.2"; 53 53 src = builtins.path { 54 54 path = ./.; 55 55 name = "statix"; ··· 75 75 }; 76 76 }; 77 77 78 + statix-vim = 79 + with final; pkgs.vimUtils.buildVimPlugin { 80 + pname = "statix-vim"; 81 + version = "0.1.0"; 82 + src = ./vim-plugin; 83 + }; 84 + 78 85 }; 79 86 80 87 packages = forAllSystems (system: { 81 - inherit (nixpkgsFor."${system}") statix; 88 + inherit (nixpkgsFor."${system}") statix statix-vim; 82 89 }); 83 90 84 91 defaultPackage =
+7
lib/src/lib.rs
··· 56 56 .flat_map(|d| Some(d.suggestion.as_ref()?.at)) 57 57 .reduce(|acc, next| acc.cover(next)) 58 58 } 59 + /// A range that encompasses all the diagnostics provided in this report 60 + pub fn total_diagnostic_range(&self) -> Option<TextRange> { 61 + self.diagnostics 62 + .iter() 63 + .flat_map(|d| Some(d.at)) 64 + .reduce(|acc, next| acc.cover(next)) 65 + } 59 66 /// Unsafe but handy replacement for above 60 67 pub fn range(&self) -> TextRange { 61 68 self.total_suggestion_range().unwrap()
+8
vim-plugin/ftplugin/nix.vim
··· 1 + setlocal makeprg=statix\ check\ -o\ errfmt\ % 2 + setlocal errorformat=%f>%l:%c:%t:%n:%m 3 + 4 + augroup StatixCheck 5 + autocmd! 6 + autocmd! BufWritePost *.nix | silent make! | silent redraw! 7 + autocmd QuickFixCmdPost [^l]* cwindow 8 + augroup END
+14
vim-plugin/plugin/statix.vim
··· 1 + function! ApplyStatixSuggestion() 2 + let l:l = line('.') 3 + let l:c = col('.') 4 + let l:filter = "%!statix single -p " . l . "," . c . "" 5 + execute l:filter 6 + 7 + silent if v:shell_error == 1 8 + undo 9 + endif 10 + 11 + call cursor(l, c) 12 + endfunction 13 + 14 + nnoremap gf :call ApplyStatixSuggestion()<cr>