Nu-Lint
Linter for the innovative Nu shell.
Learning to use a new shell is a radical change that can use some assistance. This project is aimed at helping new and intermediate users of the Nu shell. Nu shell has a lot of useful features not found in other scripting languages. This linter will give you hints to use all of them and even offer automatic fixes.
Example
The rule turn_positional_into_stream_input recommends to use pipelines instead of positional arguments:
def filter-positive [numbers] {
$numbers | where $it > 0
}
def filter-positive [] {
where $it > 0
}
This encourages lazy pipeline input: a positional list argument loads all data into memory at once, while implicit pipeline input processes elements one at a time.
Usage
(Editor integration is available, see below)
Lint all Nu files in working directory with:
To see all options and get help:
Rules
All rules are optional and can be disabled with a configuration file. The rule definitions are compatible with:
- The official Nu parser nu-parser.
- The TreeSitter-based Nu formatter topiary-nushell.
- The official Nu style guide
Some of the rules need further testing and improvement. Please make an issue on the issue tracker to report any bugs. In early stages of development some rules may be replaced or renamed.
+116 rules are defined and most have automatic fixes available (list may be out-of-date):
idioms - Simplifications unique to the Nu language.
use_is_not_empty(auto-fix)dispatch_with_subcommandsitems_instead_of_transpose_each(auto-fix)merge_get_cell_path(auto-fix)merge_multiline_print(auto-fix)turn_positional_into_stream_input(auto-fix)shorten_with_compound_assignment(auto-fix)use_regex_operators(auto-fix)ansi_over_escape_codes(auto-fix)
parsing - Better ways to parse and transform text data.
lines_instead_of_split(auto-fix)never_space_split(auto-fix)from_after_parsed_open(auto-fix)lines_each_to_parse(auto-fix)open_raw_from_to_open(auto-fix)simplify_regex_parse(auto-fix)split_row_get_multistatement(auto-fix)split_row_first_last(auto-fix)split_row_get_single_pipeline(auto-fix)
dead-code - Remove unused or redundant code
avoid_self_importunnecessary_accumulateunnecessary_variable_before_return(auto-fix)redundant_ignore(auto-fix)unnecessary_mut(auto-fix)unused_helper_functions(auto-fix)script_export_main(auto-fix)string_may_be_bare(auto-fix)inline_single_use_function
posix - Replace common bash/POSIX patterns.
ignore_over_dev_null(auto-fix)missing_stdin_in_shebang(auto-fix)use_builtin_awk(auto-fix)use_builtin_bat(auto-fix)use_builtin_cat(auto-fix)use_builtin_cut(auto-fix)use_builtin_date(auto-fix)echo_just_identity(auto-fix)use_builtin_find(auto-fix)use_builtin_grep(auto-fix)head_to_first(auto-fix)use_builtin_cd(auto-fix)use_builtin_ls(auto-fix)use_builtin_pager(auto-fix)use_builtin_read(auto-fix)use_builtin_sed(auto-fix)use_builtin_sort(auto-fix)use_builtin_tac(auto-fix)tail_to_last(auto-fix)use_builtin_uniq(auto-fix)use_builtin_wc(auto-fix)
iteration - Better patterns for loops and iteration.
replace_loop_counter_with_rangereplace_counter_while_with_each
runtime-errors - Preventing unexpected runtime behaviour.
check_complete_exit_codedescriptive_error_messagesescape_string_interpolation_operatorsexit_only_in_maincheck_typed_flag_before_usenon_final_failure_checkerror_make_for_non_fatal(auto-fix)try_instead_of_dounsafe_dynamic_record_access(auto-fix)
filtering - Better patterns for filtering and selecting data.
each_if_to_where(auto-fix)for_filter_to_whereomit_it_in_row_condition(auto-fix)where_or_filter_closure_to_it_row_condition(auto-fix)remove_redundant_in(auto-fix)
performance - Rules with potential performance impact
avoid_nu_subprocessdispatch_with_subcommandsavoid_self_importturn_positional_into_stream_input(auto-fix)unnecessary_accumulatemerge_multiline_print(auto-fix)
type-safety - Annotate with type hints where possible.
external_script_as_argumentadd_type_hints_arguments(auto-fix)prefer_path_type(auto-fix)missing_output_type(auto-fix)missing_in_type(auto-fix)
documentation - Improve actionability of user-facing messages.
add_doc_comment_exported_fndescriptive_error_messagesadd_label_to_erroradd_help_to_erroradd_span_to_labeladd_url_to_errormain_positional_args_docsmain_named_args_docsmax_positional_params
effects - Handle built-in and external commands with side-effects.
dangerous_file_operationserrors_to_stderrdont_mix_different_effectsprint_and_return_datasilence_side_effect_only_each(auto-fix)silence_stderr_data
external - Replace common external CLI tools.
use_builtin_curl(auto-fix)use_builtin_eza(auto-fix)use_builtin_fd(auto-fix)replace_jq_with_nu_get(auto-fix)use_builtin_rg(auto-fix)use_builtin_wget(auto-fix)use_builtin_which(auto-fix)
formatting - Formatting according to Nushell guidelines.
ansi_over_escape_codes(auto-fix)collapsible_if(auto-fix)forbid_excessive_nestingmax_function_body_lengthreplace_if_else_chain_with_match(auto-fix)curly_block_body_spacing(auto-fix)curly_closure_param_spacing(auto-fix)no_trailing_spaces(auto-fix)omit_list_commas(auto-fix)pipe_spacing(auto-fix)curly_record_spacing(auto-fix)reflow_wide_pipelines(auto-fix)reflow_wide_lists(auto-fix)wrap_wide_records(auto-fix)
naming - Follow official naming conventions
kebab_case_commandsscreaming_snake_constantssnake_case_variables(auto-fix)add_label_to_error
upstream - Forward warnings and errors of the upstream Nushell parser.
dynamic_script_importnu_deprecatednu_parse_error
Installation
From crates.io:
Source
Build from source:
Nix
Run without installing (using flakes):
Editor extension
VS Code extension
Available at VS Code Marketplace.
Helix
Add to your ~/.config/helix/languages.toml:
[]
= "nu-lint"
= ["--lsp"]
[[]]
= "nu"
= ["nu-lint"]
The official Nu LSP server offers completion and some other hints. It should be configured out of the box for new Helix installations and environments that have Nushell installed.
Neovim
Add to your Neovim configuration (Lua):
vim.. =
vim..
You may want to configure official Nu language server in addition to this linter, see nu --lsp command.
Emacs
Add to your Emacs configuration (with Eglot, built-in since Emacs 29):
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs
'(nushell-mode "nu-lint" "--lsp")))
Kate
Add to your ~/.config/kate/lspclient/settings.json:
Other
You can also implement your own editor extensions using the --lsp flag as in: nu-lint --lsp. This will spawn a language server compliant with the Language Server Protocol.
Configuration
Create .nu-lint.toml in your project root:
# This rule is ignored
= ["snake_case_variables"]
# Some rules are configurable
= 80
= "start"
# Set lint level of a set of rules at once.
[]
= "warning"
= "error"
# Override a single rule level
[]
= "hint"