diff --git a/.gitmodules b/.gitmodules index 7de9fd0d02..6bc1547eb9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -884,6 +884,9 @@ [submodule "vendor/grammars/nix-linguist"] path = vendor/grammars/nix-linguist url = https://github.com/sambacha/nix-linguist.git +[submodule "vendor/grammars/nu-grammar"] + path = vendor/grammars/nu-grammar + url = https://github.com/hustcer/nu-grammar.git [submodule "vendor/grammars/nu.tmbundle"] path = vendor/grammars/nu.tmbundle url = https://github.com/jsallis/nu.tmbundle diff --git a/grammars.yml b/grammars.yml index 052574ba58..e624e10251 100644 --- a/grammars.yml +++ b/grammars.yml @@ -830,6 +830,8 @@ vendor/grammars/nesC: - source.nesc vendor/grammars/nix-linguist: - source.nix +vendor/grammars/nu-grammar: +- source.nushell vendor/grammars/nu.tmbundle: - source.nu vendor/grammars/objective-c.tmbundle: diff --git a/lib/linguist/heuristics.yml b/lib/linguist/heuristics.yml index 147b2c4635..755d454c24 100644 --- a/lib/linguist/heuristics.yml +++ b/lib/linguist/heuristics.yml @@ -147,7 +147,7 @@ disambiguations: - named_pattern: vb-class - pattern: '^\s*BEGIN\R\s*MultiUse\s*=.*\R\s*Persistable\s*=' - language: VBA - named_pattern: vb-class + named_pattern: vb-class - language: TeX pattern: '^\s*\\(?:NeedsTeXFormat|ProvidesClass){' - language: ObjectScript @@ -258,7 +258,7 @@ disambiguations: - language: Visual Basic 6.0 and: - named_pattern: vb-form - - pattern: '^\s*Begin\s+VB\.Form\s+' + - pattern: '^\s*Begin\s+VB\.Form\s+' - extensions: ['.fs'] rules: - language: Forth @@ -478,6 +478,11 @@ disambiguations: - language: NL pattern: '^(b|g)[0-9]+ ' - language: NewLisp +- extensions: ['.nu'] + rules: + - language: Nushell + pattern: '^\s*(import|export|module|def|let|let-env) ' + - language: Nu - extensions: ['.odin'] rules: - language: Object Data Instance Notation diff --git a/lib/linguist/languages.yml b/lib/linguist/languages.yml index b9139595b4..5981c3c6f2 100644 --- a/lib/linguist/languages.yml +++ b/lib/linguist/languages.yml @@ -4524,6 +4524,21 @@ Nunjucks: tm_scope: text.html.nunjucks ace_mode: nunjucks language_id: 461856962 +Nushell: + type: programming + color: "#4E9906" + extensions: + - ".nu" + interpreters: + - nu + aliases: + - nu-script + - nushell-script + tm_scope: source.nushell + ace_mode: sh + codemirror_mode: shell + codemirror_mime_type: text/x-sh + language_id: 446573572 OASv2-json: type: data color: "#85ea2d" diff --git a/samples/Nushell/release-pkg.nu b/samples/Nushell/release-pkg.nu new file mode 100755 index 0000000000..08da4b99a5 --- /dev/null +++ b/samples/Nushell/release-pkg.nu @@ -0,0 +1,179 @@ +#!/usr/bin/env nu + +# Created: 2022/05/26 19:05:20 +# Description: +# A script to do the github release task, need nushell to be installed. + +# The main binary file to be released +let bin = 'nu' +let os = $env.OS +let target = $env.TARGET +# Repo source dir like `/home/runner/work/nushell/nushell` +let src = $env.GITHUB_WORKSPACE +let flags = $env.TARGET_RUSTFLAGS +let dist = $'($env.GITHUB_WORKSPACE)/output' +let version = (open Cargo.toml | get package.version) + +print $'Debugging info:' +print { version: $version, bin: $bin, os: $os, target: $target, src: $src, flags: $flags, dist: $dist }; hr-line -b + +# $env + +let USE_UBUNTU = 'ubuntu-20.04' + +print $'(char nl)Packaging ($bin) v($version) for ($target) in ($src)...'; hr-line -b +if not ('Cargo.lock' | path exists) { cargo generate-lockfile } + +print $'Start building ($bin)...'; hr-line + +# ---------------------------------------------------------------------------- +# Build for Ubuntu and macOS +# ---------------------------------------------------------------------------- +if $os in [$USE_UBUNTU, 'macos-latest'] { + if $os == $USE_UBUNTU { + sudo apt update + sudo apt-get install libxcb-composite0-dev -y + } + match $target { + 'aarch64-unknown-linux-gnu' => { + sudo apt-get install gcc-aarch64-linux-gnu -y + let-env CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER = 'aarch64-linux-gnu-gcc' + cargo-build-nu $flags + } + 'riscv64gc-unknown-linux-gnu' => { + sudo apt-get install gcc-riscv64-linux-gnu -y + let-env CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_LINKER = 'riscv64-linux-gnu-gcc' + cargo-build-nu $flags + } + 'armv7-unknown-linux-gnueabihf' => { + sudo apt-get install pkg-config gcc-arm-linux-gnueabihf -y + let-env CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER = 'arm-linux-gnueabihf-gcc' + cargo-build-nu $flags + } + _ => { + # musl-tools to fix 'Failed to find tool. Is `musl-gcc` installed?' + # Actually just for x86_64-unknown-linux-musl target + if $os == $USE_UBUNTU { sudo apt install musl-tools -y } + cargo-build-nu $flags + } + } +} + +# ---------------------------------------------------------------------------- +# Build for Windows without static-link-openssl feature +# ---------------------------------------------------------------------------- +if $os in ['windows-latest'] { + if ($flags | str trim | is-empty) { + cargo build --release --all --target $target + } else { + cargo build --release --all --target $target $flags + } +} + +# ---------------------------------------------------------------------------- +# Prepare for the release archive +# ---------------------------------------------------------------------------- +let suffix = if $os == 'windows-latest' { '.exe' } +# nu, nu_plugin_* were all included +let executable = $'target/($target)/release/($bin)*($suffix)' +print $'Current executable file: ($executable)' + +cd $src; mkdir $dist; +rm -rf $'target/($target)/release/*.d' $'target/($target)/release/nu_pretty_hex*' +print $'(char nl)All executable files:'; hr-line +# We have to use `print` here to make sure the command output is displayed +print (ls -f $executable); sleep 1sec + +print $'(char nl)Copying release files...'; hr-line +cp -v README.release.txt $'($dist)/README.txt' +[LICENSE $executable] | each {|it| cp -rv $it $dist } | flatten +# Sleep a few seconds to make sure the cp process finished successfully +sleep 3sec + +print $'(char nl)Check binary release version detail:'; hr-line +let ver = if $os == 'windows-latest' { + (do -i { ./output/nu.exe -c 'version' }) | str join +} else { + (do -i { ./output/nu -c 'version' }) | str join +} +if ($ver | str trim | is-empty) { + print $'(ansi r)Incompatible nu binary...(ansi reset)' +} else { print $ver } + +# ---------------------------------------------------------------------------- +# Create a release archive and send it to output for the following steps +# ---------------------------------------------------------------------------- +cd $dist; print $'(char nl)Creating release archive...'; hr-line +if $os in [$USE_UBUNTU, 'macos-latest'] { + + let files = (ls | get name) + let dest = $'($bin)-($version)-($target)' + let archive = $'($dist)/($dest).tar.gz' + + mkdir $dest + $files | each {|it| mv $it $dest } | ignore + + print $'(char nl)(ansi g)Archive contents:(ansi reset)'; hr-line; ls $dest + + tar -czf $archive $dest + print $'archive: ---> ($archive)'; ls $archive + # REF: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/ + echo $"archive=($archive)" | save --append $env.GITHUB_OUTPUT + +} else if $os == 'windows-latest' { + + let releaseStem = $'($bin)-($version)-($target)' + + print $'(char nl)Download less related stuffs...'; hr-line + aria2c https://github.com/jftuga/less-Windows/releases/download/less-v608/less.exe -o less.exe + aria2c https://raw.githubusercontent.com/jftuga/less-Windows/master/LICENSE -o LICENSE-for-less.txt + + # Create Windows msi release package + if (get-env _EXTRA_) == 'msi' { + + let wixRelease = $'($src)/target/wix/($releaseStem).msi' + print $'(char nl)Start creating Windows msi package...' + cd $src; hr-line + # Wix need the binaries be stored in target/release/ + cp -r $'($dist)/*' target/release/ + cargo install cargo-wix --version 0.3.4 + cargo wix --no-build --nocapture --package nu --output $wixRelease + print $'archive: ---> ($wixRelease)'; + echo $"archive=($wixRelease)" | save --append $env.GITHUB_OUTPUT + + } else { + + print $'(char nl)(ansi g)Archive contents:(ansi reset)'; hr-line; ls + let archive = $'($dist)/($releaseStem).zip' + 7z a $archive * + print $'archive: ---> ($archive)'; + let pkg = (ls -f $archive | get name) + if not ($pkg | is-empty) { + echo $"archive=($pkg | get 0)" | save --append $env.GITHUB_OUTPUT + } + } +} + +def 'cargo-build-nu' [ options: string ] { + if ($options | str trim | is-empty) { + cargo build --release --all --target $target --features=static-link-openssl + } else { + cargo build --release --all --target $target --features=static-link-openssl $options + } +} + +# Print a horizontal line marker +def 'hr-line' [ + --blank-line(-b): bool +] { + print $'(ansi g)---------------------------------------------------------------------------->(ansi reset)' + if $blank_line { char nl } +} + +# Get the specified env key's value or '' +def 'get-env' [ + key: string # The key to get it's env value + default: string = '' # The default value for an empty env +] { + $env | get -i $key | default $default +} diff --git a/samples/Nushell/this_week_in_nu.nu b/samples/Nushell/this_week_in_nu.nu new file mode 100644 index 0000000000..e4e74c0e26 --- /dev/null +++ b/samples/Nushell/this_week_in_nu.nu @@ -0,0 +1,63 @@ +# http get https://api.github.com/repos/nushell/nushell/pulls?q=is%3Apr+merged%3A%3E%3D2021-04-20+ | select html_url user.login title body +# http get https://api.github.com/search/issues?q=repo:nushell/nushell+is:pr+is:merged+merged:%3E2021-05-08 | get items | select html_url user.login title body +# Repos to monitor + +def query-week-span [] { + let site_table = [ + [site repo]; + [Nushell nushell] + [Extension vscode-nushell-lang] + [Documentation nushell.github.io] + [Wasm demo] + [Nu_Scripts nu_scripts] + [RFCs rfcs] + [reedline reedline] + [Nana nana] + # ] [Jupyter jupyter] + ] + + let query_prefix = "https://api.github.com/search/issues?q=repo:nushell/" + let query_date = (seq date --days 7 -r | get 6) + let per_page = "100" + let page_num = "1" # need to implement iterating pages + let colon = "%3A" + let gt = "%3E" + let eq = "%3D" + let amp = "%26" + let query_suffix = $"+is($colon)pr+is($colon)merged+merged($colon)($gt)($eq)($query_date)&per_page=100&page=1" + + for repo in $site_table { + let query_string = $"($query_prefix)($repo.repo)($query_suffix)" + let site_json = (http get -u $env.GITHUB_USERNAME -p $env.GITHUB_PASSWORD $query_string | get items | select html_url user.login title) + + if not ($site_json | all { |it| $it | is-empty }) { + print $"(char nl)## ($repo.site)(char nl)" + + for user in ($site_json | group-by user_login | transpose user prs) { + let user_name = $user.user + let pr_count = ($user.prs | length) + + print -n $"- ($user_name) created " + for pr in ($user.prs | enumerate) { + if $pr_count == ($pr.index + 1) { + print -n $"[($pr.item.title)](char lparen)($pr.item.html_url)(char rparen)" + } else { + print -n $"[($pr.item.title)](char lparen)($pr.item.html_url)(char rparen), and " + } + } + + print "" + } + } + } +} + +# 2019-08-23 was the release of 0.2.0, the first public release +let week_num = ((seq date -b '2019-08-23' -n 7 | length) - 1) +print $"# This week in Nushell #($week_num)(char nl)" + +if ($env | select GITHUB_USERNAME | is-empty) or ($env | select GITHUB_PASSWORD | is-empty) { + print 'Please set GITHUB_USERNAME and GITHUB_PASSWORD in $env to use this script' +} else { + query-week-span +} diff --git a/test/test_heuristics.rb b/test/test_heuristics.rb index c8f51086c0..a0e28f2e9d 100755 --- a/test/test_heuristics.rb +++ b/test/test_heuristics.rb @@ -430,7 +430,7 @@ def test_fr_by_heuristics "Text" => all_fixtures("Text", "*.fr") }) end - + def test_frm_by_heuristics assert_heuristics({ "VBA" => all_fixtures("VBA", "*.frm"), @@ -705,6 +705,13 @@ def test_nl_by_heuristics }) end + def test_nu_by_heuristics + assert_heuristics({ + "Nushell" => all_fixtures("Nushell", "*.nu"), + "Nu" => all_fixtures("Nu", "*.nu") + }) + end + def test_odin_by_heuristics assert_heuristics({ "Object Data Instance Notation" => all_fixtures("Object Data Instance Notation", "*.odin"), diff --git a/vendor/README.md b/vendor/README.md index f94010a8a5..71045b5ca1 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -363,6 +363,7 @@ This is a list of grammars that Linguist selects to provide syntax highlighting - **Nix:** [sambacha/nix-linguist](https://github.com/sambacha/nix-linguist) - **Nu:** [jsallis/nu.tmbundle](https://github.com/jsallis/nu.tmbundle) - **Nunjucks:** [alohaas/language-nunjucks](https://github.com/alohaas/language-nunjucks) +- **Nushell:** [hustcer/nu-grammar](https://github.com/hustcer/nu-grammar) - **OASv2-json:** [Nixinova/NovaGrammars](https://github.com/Nixinova/NovaGrammars) - **OASv2-yaml:** [atom/language-yaml](https://github.com/atom/language-yaml) - **OASv3-json:** [Nixinova/NovaGrammars](https://github.com/Nixinova/NovaGrammars) diff --git a/vendor/grammars/nu-grammar b/vendor/grammars/nu-grammar new file mode 160000 index 0000000000..e318054f5d --- /dev/null +++ b/vendor/grammars/nu-grammar @@ -0,0 +1 @@ +Subproject commit e318054f5d9cae03c2b0d39a2ce95d2ad6a98116 diff --git a/vendor/licenses/git_submodule/nu-grammar.dep.yml b/vendor/licenses/git_submodule/nu-grammar.dep.yml new file mode 100644 index 0000000000..5ba5ede2bf --- /dev/null +++ b/vendor/licenses/git_submodule/nu-grammar.dep.yml @@ -0,0 +1,31 @@ +--- +name: nu-grammar +version: e318054f5d9cae03c2b0d39a2ce95d2ad6a98116 +type: git_submodule +homepage: https://github.com/hustcer/nu-grammar.git +license: mit +licenses: +- sources: LICENSE + text: | + MIT License + + Copyright (c) 2019 - 2023 The Nushell Project Developers + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +notices: []