Created
November 7, 2023 23:03
-
-
Save tynanbe/dc10df454257606533abdeb145ddeeed to your computer and use it in GitHub Desktop.
POSIX shell scripts and Helix config to auto-select when to use Deno, TS LS, and/or Prettier for the current file. Bonus script to auto-update Helix grammars.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# Runs `deno lsp` if a Deno configuration file is found, otherwise runs | |
# `typescript-language-server` | |
# | |
# Usage: deno_lsp_or_tsls ...[arguments] | |
# | |
# This script is intended to be run by the Helix editor, or any other editor | |
# that includes the current buffer's filename as the final field in its process | |
# command line. | |
# | |
set -e | |
PATH="$(dirname "$(realpath "${0}")"):${PATH}" | |
file=$( | |
ps -p "${PPID}" -o "command=" \ | |
| awk '{ print $NF }' | |
) | |
prev="" | |
dir=$(dirname "$(realpath "${file}")") | |
cd "${dir}" | |
file=$(basename "${file}") | |
should_deno_lsp() ( | |
case "${dir}" in | |
"${prev}") return 1 ;; | |
*) | |
if test -r "deno.json" \ | |
-o -r "deno.jsonc"; then | |
return 0 | |
elif test -r "package.json"; then | |
return 1 | |
else | |
cd .. | |
prev="${dir}" | |
dir=$(pwd) | |
should_deno_lsp | |
fi | |
;; | |
esac | |
) | |
if should_deno_lsp; then | |
if qtype deno; then | |
exec deno lsp --unstable "${@}" | |
fi | |
elif qtype typescript-language-server; then | |
exec typescript-language-server --stdio "${@}" | |
fi | |
exit 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# Updates Helix grammars defined in `${XDG_CONFIG_HOME}/helix/languages.toml` if | |
# any new revisions are found | |
# | |
# Usage: hx_grammars | |
# | |
# All grammars are compiled, but only those specified in `languages.toml` are | |
# retained. | |
# | |
set -e | |
PATH="$(dirname "$(realpath "${0}")"):${PATH}" | |
qtype git hx jq toml | |
helix_dir="${XDG_CONFIG_HOME}/helix" | |
grammars_dir="${helix_dir}/runtime/grammars" | |
languages="${helix_dir}/languages.toml" | |
# Get latest git revisions for grammars defined in `${languages}` | |
# | |
grammar_names="" | |
do_update="False" | |
grammars=$( | |
toml get "${languages}" grammar \ | |
| jq '.[] | "name=\"\(.name)\";repo=\"\(.source.git)\";current_revision=\"\(.source.rev)\""' --raw-output | |
) | |
cd "/tmp/" | |
for grammar in ${grammars}; do | |
name="None" | |
repo="None" | |
current_revision="None" | |
eval "${grammar}" | |
case "${name}${repo}${current_revision}" in | |
*None*) continue ;; | |
esac | |
grammar_names=$( | |
case "${grammar_names}" in | |
"") echo "${name}" ;; | |
*) echo "${grammar_names}" "${name}" ;; | |
esac | |
) | |
repo_dir=$(basename "${repo}") | |
echo "Searching for ${name} grammar updates..." | |
git clone --depth=1 --quiet "${repo}.git" | |
cd "${repo_dir}" | |
new_revision=$(git rev-parse HEAD) | |
cd "/tmp/" | |
rm -rf "${repo_dir}" | |
case "${new_revision}" in | |
"${current_revision}") continue ;; | |
*) | |
do_update="True" | |
sed -i "s/${current_revision}/${new_revision}/" "${languages}" | |
;; | |
esac | |
done | |
# Update compiled grammars if needed | |
# | |
case "${do_update}" in | |
True) echo "Compiling new grammars..." ;; | |
False) | |
echo "No new grammars found" | |
exit 0 | |
;; | |
esac | |
for action in fetch build; do | |
hx --grammar "${action}" >/dev/null | |
done | |
rm -rf "${grammars_dir}/sources/" | |
for grammar in ${grammar_names}; do | |
cp "${grammars_dir}/${grammar}.so" "/tmp/" | |
done | |
rm -rf "${grammars_dir}" | |
mkdir -p "${grammars_dir}" | |
for grammar in ${grammar_names}; do | |
mv "/tmp/${grammar}.so" "${grammars_dir}/" | |
done | |
echo "Grammars updated" | |
exit 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[[language]] | |
name = "bash" | |
auto-format = true | |
[language.formatter] | |
command = "shfmt" | |
args = [ | |
"--binary-next-line", | |
"--case-indent", | |
"--indent=2", | |
"--simplify", | |
] | |
[[language]] | |
name = "elixir" | |
auto-format = true | |
[[grammar]] | |
name = "elixir" | |
[grammar.source] | |
git = "https://github.com/elixir-lang/tree-sitter-elixir" | |
rev = "a2861e88a730287a60c11ea9299c033c7d076e30" | |
[[language]] | |
name = "erlang" | |
auto-format = true | |
[[grammar]] | |
name = "erlang" | |
[grammar.source] | |
git = "https://github.com/the-mikedavis/tree-sitter-erlang" | |
rev = "bf56054c7c1bc66a27552b19702ffac8189ac7ec" | |
[[language]] | |
name = "gleam" | |
auto-format = true | |
formatter = { command = "gleam", args = ["format", "--stdin"] } | |
[[grammar]] | |
name = "gleam" | |
[grammar.source] | |
git = "https://github.com/gleam-lang/tree-sitter-gleam" | |
rev = "399172f660160258ede7d8e1d769f7fc5f61ff33" | |
[[language]] | |
name = "javascript" | |
auto-format = true | |
formatter = { command = "prettier_or_deno_fmt" } | |
language-servers = ["deno-lsp-or-tsls"] | |
[[language]] | |
name = "json" | |
auto-format = true | |
formatter = { command = "prettier_or_deno_fmt" } | |
[[language]] | |
name = "markdown" | |
auto-format = true | |
formatter = { command = "prettier_or_deno_fmt" } | |
[[language]] | |
name = "php" | |
indent = { tab-width = 2, unit = "\t" } | |
[[language]] | |
name = "sql" | |
auto-format = true | |
formatter = { command = "prettier", args = ["--stdin-filepath=query.sql", "--config-precedence=file-override", "--sql-keyword-case=lower"] } | |
[[language]] | |
name = "typescript" | |
auto-format = true | |
formatter = { command = "prettier_or_deno_fmt" } | |
language-servers = ["deno-lsp-or-tsls"] | |
[language-server.deno-lsp-or-tsls] | |
command = "deno_lsp_or_tsls" | |
environment = { NO_COLOR = "1" } | |
config.hostInfo = "helix" | |
[language-server.deno-lsp-or-tsls.config.deno] | |
enable = true | |
unstable = true | |
cacheOnSave = true | |
suggest = { completeFunctionCalls = false, imports = { hosts = { "https://deno.land" = true } } } | |
# suggest = { completeFunctionCalls = false, imports = { hosts = { "https://deno.land" = true, "https://crux.land" = true, "https://x.nest.land" = true } } } | |
inlayHints.parameterNames.enabled = "all" | |
inlayHints.parameterTypes.enabled = true | |
inlayHints.variableTypes.enabled = true | |
inlayHints.propertyDeclarationTypes.enabled = true | |
inlayHints.functionLikeReturnTypes.enabled = true | |
inlayHints.enumMemberValues.enabled = true | |
[language-server.deno-lsp-or-tsls.config.typescript.inlayHints] | |
includeInlayEnumMemberValueHints = true | |
includeInlayFunctionLikeReturnTypeHints = true | |
includeInlayFunctionParameterTypeHints = true | |
includeInlayParameterNameHints = "all" | |
includeInlayParameterNameHintsWhenArgumentMatchesName = true | |
includeInlayPropertyDeclarationTypeHints = true | |
includeInlayVariableTypeHints = true | |
[language-server.deno-lsp-or-tsls.config.javascript.inlayHints] | |
includeInlayEnumMemberValueHints = true | |
includeInlayFunctionLikeReturnTypeHints = true | |
includeInlayFunctionParameterTypeHints = true | |
includeInlayParameterNameHints = "all" | |
includeInlayParameterNameHintsWhenArgumentMatchesName = true | |
includeInlayPropertyDeclarationTypeHints = true | |
includeInlayVariableTypeHints = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# Formats stdin using Prettier if a configuration file is found, otherwise uses | |
# the Deno formatter | |
# | |
# Usage: prettier_or_deno_fmt | |
# | |
# This script is intended to be run by the Helix editor, or any other editor | |
# that includes the current buffer's filename as the final field in its process | |
# command line. | |
# | |
set -e | |
PATH="$(dirname "$(realpath "${0}")"):${PATH}" | |
file=$( | |
ps -p "${PPID}" -o "command=" \ | |
| awk '{ print $NF }' | |
) | |
prev="" | |
dir=$(dirname "$(realpath "${file}")") | |
cd "${dir}" | |
file=$(basename "${file}") | |
should_prettier() ( | |
case "${dir}" in | |
"${prev}") return 1 ;; | |
*) | |
if grep -iqs "prettier" "package.json" \ | |
|| test -r ".prettierrc" \ | |
-o -r ".prettierrc.json" \ | |
-o -r ".prettierrc.yml" \ | |
-o -r ".prettierrc.yaml" \ | |
-o -r ".prettierrc.json5" \ | |
-o -r ".prettierrc.js" \ | |
-o -r ".prettierrc.cjs" \ | |
-o -r "prettier.config.js" \ | |
-o -r "prettier.config.cjs" \ | |
-o -r ".prettierrc.toml"; then | |
return 0 | |
elif test -r "deno.json" \ | |
-o -r "deno.jsonc"; then | |
return 1 | |
else | |
cd .. | |
prev="${dir}" | |
dir=$(pwd) | |
should_prettier | |
fi | |
;; | |
esac | |
) | |
if should_prettier; then | |
if qtype prettier; then | |
exec prettier \ | |
--loglevel=silent \ | |
--stdin-filepath="${file}" | |
fi | |
elif qtype deno; then | |
case "${file}" in | |
.*.*) ext="${file##*.}" ;; | |
.*) ext="" ;; | |
*.*) ext="${file##*.}" ;; | |
*) ext="" ;; | |
esac | |
exec deno fmt \ | |
--ext="${ext}" \ | |
--quiet \ | |
--unstable \ | |
- | |
fi | |
exit 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment