Skip to content

Commit

Permalink
WIP nix
Browse files Browse the repository at this point in the history
  • Loading branch information
domenkozar committed Oct 17, 2024
1 parent 7b1c316 commit f11e1ae
Show file tree
Hide file tree
Showing 7 changed files with 275 additions and 36 deletions.
56 changes: 32 additions & 24 deletions topiary-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ name = "topiary-cli"
description = "CLI app for Topiary, the universal code formatter."
categories = ["command-line-utilities", "development-tools", "text-processing"]
keywords = [
"cli",
"code-formatter",
"formatter",
"text",
"tree-sitter",
"utility",
"cli",
"code-formatter",
"formatter",
"text",
"tree-sitter",
"utility",
]
version.workspace = true
edition.workspace = true
Expand All @@ -35,7 +35,12 @@ itertools = { workspace = true }
log = { workspace = true }
serde = { workspace = true, features = ["derive"] }
tempfile = { workspace = true }
tokio = { workspace = true, features = ["fs", "rt-multi-thread", "sync", "macros"] }
tokio = { workspace = true, features = [
"fs",
"rt-multi-thread",
"sync",
"macros",
] }
toml = { workspace = true }
topiary-core = { path = "../topiary-core" }
topiary-config = { path = "../topiary-config" }
Expand All @@ -58,34 +63,37 @@ predicates = { workspace = true }

[features]
default = [
"contributed",
"json",
"nickel",
"ocaml",
"ocaml_interface",
"ocamllex",
"toml",
"tree_sitter_query"
"contributed",
"json",
"nickel",
"nix",
"ocaml",
"ocaml_interface",
"ocamllex",
"toml",
"tree_sitter_query",
]

# Included by default
contributed = [
"css"
]
contributed = ["css"]

# Excluded by default
experimental = [
"bash",
"rust",
]
experimental = ["bash", "rust"]

nix = ["topiary-config/nix", "topiary-queries/nix"]
bash = ["topiary-config/bash", "topiary-queries/bash"]
css = ["topiary-config/css", "topiary-queries/css"]
json = ["topiary-config/json", "topiary-queries/json"]
nickel = ["topiary-config/nickel", "topiary-queries/nickel"]
ocaml = ["topiary-config/ocaml", "topiary-queries/ocaml"]
ocaml_interface = ["topiary-config/ocaml_interface", "topiary-queries/ocaml_interface"]
ocaml_interface = [
"topiary-config/ocaml_interface",
"topiary-queries/ocaml_interface",
]
ocamllex = ["topiary-config/ocamllex", "topiary-queries/ocamllex"]
rust = ["topiary-config/rust", "topiary-queries/rust"]
toml = ["topiary-config/toml", "topiary-queries/toml"]
tree_sitter_query = ["topiary-config/tree_sitter_query", "topiary-queries/tree_sitter_query"]
tree_sitter_query = [
"topiary-config/tree_sitter_query",
"topiary-queries/tree_sitter_query",
]
3 changes: 3 additions & 0 deletions topiary-cli/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,9 @@ where
#[cfg(feature = "toml")]
"toml" => Ok(topiary_queries::toml().into()),

#[cfg(feature = "nix")]
"nix" => Ok(topiary_queries::nix().into()),

#[cfg(feature = "tree_sitter_query")]
"tree_sitter_query" => Ok(topiary_queries::tree_sitter_query().into()),

Expand Down
26 changes: 14 additions & 12 deletions topiary-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ git2.workspace = true
libloading.workspace = true

[features]
default = [ "parallel" ]
default = ["parallel"]

# Enabling the `parallel` feature enables parallel computation where possible.
# At the moment, this is only in grammar prefetching
parallel = [ "dep:rayon" ]
parallel = ["dep:rayon"]

bash = []
css = []
Expand All @@ -46,21 +46,23 @@ nickel = []
ocaml = []
ocaml_interface = []
ocamllex = []
nix = []
rust = []
toml = []
tree_sitter_query = []

# This a convenience for the sake of downstream applications which don't
# wish to cherry-pick grammars (e.g., the playground)
all = [
"bash",
"css",
"json",
"nickel",
"ocaml",
"ocaml_interface",
"ocamllex",
"rust",
"toml",
"tree_sitter_query"
"bash",
"css",
"json",
"nickel",
"ocaml",
"ocaml_interface",
"ocamllex",
"rust",
"nix",
"toml",
"tree_sitter_query",
]
8 changes: 8 additions & 0 deletions topiary-config/languages.ncl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@
},
},

nix = {
extensions = ["nix"],
grammar = {
git = "https://github.com/nix-community/tree-sitter-nix",
rev = "456b14a2fa6315abc7e02fcffaf4a1f35d4955d3",
},
},

json = {
extensions = [
"json",
Expand Down
1 change: 1 addition & 0 deletions topiary-queries/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ ocaml_interface = []
ocamllex = []
rust = []
toml = []
nix = []
tree_sitter_query = []
211 changes: 211 additions & 0 deletions topiary-queries/queries/nix.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
;; Nix Formatter based on RFC 166

; Leaf nodes
[
(string_expression)
(integer_expression)
(float_expression)
(uri_expression)
(path_expression)
(hpath_expression)
(spath_expression)
] @leaf

; Comments
(comment) @comment

; Convert single-line /* */ comments to #
(comment) @convert_to_hash_comment

; Preserve multiline comments
(comment) @preserve_multiline_comment

; Append space after specific tokens
":" @append_space
"=" @prepend_space @append_space
"," @append_spaced_softline

; Handle indentation and line breaks
; Define softline breaks and indentation starts/ends
"{" @append_spaced_softline @append_indent_start
"}" @prepend_spaced_softline @prepend_indent_end
"[" @append_spaced_softline @append_indent_start
"]" @prepend_spaced_softline @prepend_indent_end

; Functions

(function_expression
formals: (formals
"{" @append_spaced_softline @append_indent_start
(formal) @formal_param
"}" @prepend_spaced_softline @prepend_indent_end
)
body: (_) @function_body
) @function_declaration

; Ensure each parameter is on a new line with proper indentation
(formal) @prepend_spaced_softline

; Attribute Sets

(attrset_expression
"{" @append_spaced_softline @append_indent_start
(binding_set
(binding) @attr_binding
)
"}" @prepend_spaced_softline @prepend_indent_end
) @attribute_set

; Ensure each key-value pair is on its own line
(binding
attrpath: (_) @attr_key
"=" @append_space
(_) @attr_value
";" @append_spaced_softline
)

; Lists

(list_expression
"[" @append_spaced_softline @append_indent_start
(_) @list_item
"]" @prepend_spaced_softline @prepend_indent_end
) @list

; If-Then-Else Expressions

(if_expression
"if" @keyword_if @append_space @prepend_spaced_softline
condition: (_) @if_condition
"then" @keyword_then @append_space @prepend_spaced_softline @append_indent_start
;body: (_) @if_body @append_indent_end
"else" @keyword_else @append_space @prepend_spaced_softline @append_indent_start
alternative: (_) @else_body @append_indent_end
)

; Let-In Expressions

(let_expression
"let" @keyword_let @append_spaced_softline @append_indent_start
(binding_set
(binding
attrpath: (_) @let_binding_name
"=" @append_space
(_) @let_binding_value
";" @append_spaced_softline
)+
)
"in" @keyword_in @prepend_spaced_softline @prepend_indent_end @append_spaced_softline
body: (_) @let_body
)

; With Expressions

(with_expression
"with" @keyword_with @append_space
(_) @with_expression
";" @append_spaced_softline
body: (_) @with_body
)

; Assert Expressions

(assert_expression
"assert" @keyword_assert @append_space
(_) @assert_condition
";" @append_spaced_softline
body: (_) @assert_body
)

; Operator Formatting

(binary_expression
left: (_) @op_left
right: (_) @op_right
)

; Ensure operators start on new lines if they don't fit on a single line
(binary_expression
(_) @prepend_spaced_softline
)

; Inherit Statements

(inherit
"inherit" @keyword_inherit @append_space
(inherited_attrs
(identifier) @inherit_item
)+
";" @inherit_semicolon
)

; Handle inherit with source
(inherit_from
"inherit" @keyword_inherit @append_space
"(" @inherit_parentheses_start
(_) @inherit_source
")" @inherit_parentheses_end
(inherited_attrs
(identifier) @inherit_item
)+
";" @inherit_semicolon
)

; Empty Objects and Arrays

(attrset_expression
"{" @object_open
"}" @object_close
) @empty_attribute_set

(list_expression
"[" @array_open
"]" @array_close
) @empty_array

; String Interpolation

(interpolation
"${" @interp_start
(_) @interp_content
"}" @interp_end
)

; Additional Rules

; Handle let bindings indentation
(let_expression
(binding_set
(binding) @let_binding_indent
)
)

; Handle assertions
(assert_expression
"assert" @keyword_assert @append_space
(_) @assert_condition
";" @assert_semicolon
)

; Handle comments within expressions
(comment) @comment_within_expr

; Leaf Nodes Preservation
(_) @leaf

; Handle semicolon placement in bindings
(binding
";" @semicolon_end
)

; Handle indentation for nested attribute sets
(attrset_expression
(binding_set
(binding
(attrset_expression) @nested_attribute_set
)
)
)

; Handle newline preservation rules
(ERROR) @collapse_empty_lines
6 changes: 6 additions & 0 deletions topiary-queries/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ pub fn toml() -> &'static str {
include_str!("../queries/toml.scm")
}

/// Returns the Topiary-compatible query file for Nix.
#[cfg(feature = "nix")]
pub fn nix() -> &'static str {
include_str!("../queries/nix.scm")
}

/// Returns the Topiary-compatible query file for the
/// Tree-sitter query language.
#[cfg(feature = "tree_sitter_query")]
Expand Down

0 comments on commit f11e1ae

Please sign in to comment.