From cfe575764dfc48359ab2e21f6049d857308174cb Mon Sep 17 00:00:00 2001 From: trivernis Date: Sun, 15 Jan 2023 12:21:42 +0100 Subject: [PATCH] Remove the merge stuff --- .github/workflows/build.yml.orig | 139 --- .github/workflows/release.yml.orig | 281 ----- README.md.orig | 178 ---- book/src/generated/typable-cmd.md.orig | 84 -- helix-term/src/commands/lsp.rs.orig | 1297 ------------------------ runtime/themes/dracula.toml.orig | 84 -- runtime/themes/ingrid.toml.orig | 84 -- runtime/themes/serika-light.toml.orig | 114 --- 8 files changed, 2261 deletions(-) delete mode 100644 .github/workflows/build.yml.orig delete mode 100644 .github/workflows/release.yml.orig delete mode 100644 README.md.orig delete mode 100644 book/src/generated/typable-cmd.md.orig delete mode 100644 helix-term/src/commands/lsp.rs.orig delete mode 100644 runtime/themes/dracula.toml.orig delete mode 100644 runtime/themes/ingrid.toml.orig delete mode 100644 runtime/themes/serika-light.toml.orig diff --git a/.github/workflows/build.yml.orig b/.github/workflows/build.yml.orig deleted file mode 100644 index 526c7b3c..00000000 --- a/.github/workflows/build.yml.orig +++ /dev/null @@ -1,139 +0,0 @@ -name: Build -on: - pull_request: - push: - branches: - - master - schedule: - - cron: '00 01 * * *' - -jobs: - check: - name: Check - runs-on: ubuntu-latest - strategy: - matrix: - rust: [stable, msrv] - steps: - - name: Checkout sources - uses: actions/checkout@v3 - - - name: Use MSRV rust toolchain - if: matrix.rust == 'msrv' - run: cp .github/workflows/msrv-rust-toolchain.toml rust-toolchain.toml - - - name: Install stable toolchain - uses: helix-editor/rust-toolchain@v1 - with: - profile: minimal - override: true - - - uses: Swatinem/rust-cache@v2 - - - name: Run cargo check - run: cargo check - - test: - name: Test Suite - runs-on: ${{ matrix.os }} - env: - RUST_BACKTRACE: 1 - HELIX_LOG_LEVEL: info - steps: - - name: Checkout sources - uses: actions/checkout@v3 - - - name: Install stable toolchain - uses: helix-editor/rust-toolchain@v1 - with: - profile: minimal - override: true - - - uses: Swatinem/rust-cache@v2 - - - name: Cache test tree-sitter grammar - uses: actions/cache@v3 - with: - path: runtime/grammars - key: ${{ runner.os }}-stable-v${{ env.CACHE_VERSION }}-tree-sitter-grammars-${{ hashFiles('languages.toml') }} - restore-keys: ${{ runner.os }}-stable-v${{ env.CACHE_VERSION }}-tree-sitter-grammars- - - - name: Run cargo test - run: cargo test --workspace - - - name: Run cargo integration-test - run: cargo integration-test - - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - - lints: - name: Lints - runs-on: ubuntu-latest - steps: - - name: Checkout sources - uses: actions/checkout@v3 - - - name: Install stable toolchain - uses: helix-editor/rust-toolchain@v1 - with: - profile: minimal - override: true - components: rustfmt, clippy - - - uses: Swatinem/rust-cache@v2 - - - name: Run cargo fmt - run: cargo fmt --all -- --check - - - name: Run cargo clippy - run: cargo clippy --workspace --all-targets -- -D warnings - - - name: Run cargo doc - run: cargo doc --no-deps --workspace --document-private-items - env: - RUSTDOCFLAGS: -D warnings - - docs: - name: Docs - runs-on: ubuntu-latest - steps: - - name: Checkout sources - uses: actions/checkout@v3 - - - name: Install stable toolchain - uses: helix-editor/rust-toolchain@v1 - with: - profile: minimal - override: true - - - uses: Swatinem/rust-cache@v2 - - - name: Generate docs - run: cargo xtask docgen - - - name: Check uncommitted documentation changes - run: | - git diff - git diff-files --quiet \ - || (echo "Run 'cargo xtask docgen', commit the changes and push again" \ - && exit 1) - - queries: - name: Tree-sitter queries - runs-on: ubuntu-latest - steps: - - name: Checkout sources - uses: actions/checkout@v3 - - - name: Install stable toolchain - uses: helix-editor/rust-toolchain@v1 - with: - profile: minimal - override: true - - - uses: Swatinem/rust-cache@v2 - - - name: Generate docs - run: cargo xtask query-check diff --git a/.github/workflows/release.yml.orig b/.github/workflows/release.yml.orig deleted file mode 100644 index 1c1546a2..00000000 --- a/.github/workflows/release.yml.orig +++ /dev/null @@ -1,281 +0,0 @@ -name: Release -on: - push: - tags: - -env: - # Preview mode: Publishes the build output as a CI artifact instead of creating - # a release, allowing for manual inspection of the output. This mode is - # activated if the CI run was triggered by events other than pushed tags, or - # if the repository is a fork. - preview: ${{ !startsWith(github.ref, 'refs/tags/')}} - -jobs: - fetch-grammars: - name: Fetch Grammars - runs-on: ubuntu-latest - steps: - - name: Checkout sources - uses: actions/checkout@v3 - - - name: Install stable toolchain - uses: dtolnay/rust-toolchain@stable - - - uses: Swatinem/rust-cache@v2 - - - name: Fetch tree-sitter grammars - run: cargo run --package=helix-loader --bin=hx-loader - - - name: Bundle grammars - run: tar cJf grammars.tar.xz -C runtime/grammars/sources . - - - uses: actions/upload-artifact@v3 - with: - name: grammars - path: grammars.tar.xz - - dist: - name: Dist - needs: [fetch-grammars] - env: - # For some builds, we use cross to test on 32-bit and big-endian - # systems. - CARGO: cargo - # When CARGO is set to CROSS, this is set to `--target matrix.target`. - TARGET_FLAGS: - # When CARGO is set to CROSS, TARGET_DIR includes matrix.target. - TARGET_DIR: ./target - # Emit backtraces on panics. - RUST_BACKTRACE: 1 - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false # don't fail other jobs if one fails - matrix: - build: [x86_64-linux, x86_64-macos, x86_64-windows] #, x86_64-win-gnu, win32-msvc - include: - - build: x86_64-linux - os: ubuntu-latest - rust: stable - target: x86_64-unknown-linux-gnu - cross: false - - build: aarch64-linux - os: ubuntu-latest - rust: stable - target: aarch64-unknown-linux-gnu - cross: true - - build: riscv64-linux - os: ubuntu-latest - rust: stable - target: riscv64gc-unknown-linux-gnu - cross: true - - build: x86_64-macos - os: macos-latest - rust: stable - target: x86_64-apple-darwin - cross: false - - build: x86_64-windows - os: windows-latest - rust: stable - target: x86_64-pc-windows-msvc - cross: false - - build: aarch64-macos - os: macos-latest - rust: stable - target: aarch64-apple-darwin - cross: false - skip_tests: true # x86_64 host can't run aarch64 code - - steps: - - name: Checkout sources - uses: actions/checkout@v3 - - - name: Download grammars - uses: actions/download-artifact@v3 - - - name: Move grammars under runtime - if: "!startsWith(matrix.os, 'windows')" - run: | - mkdir -p runtime/grammars/sources - tar xJf grammars/grammars.tar.xz -C runtime/grammars/sources - - - name: Install ${{ matrix.rust }} toolchain - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - - # Install a pre-release version of Cross - # TODO: We need to pre-install Cross because we need cross-rs/cross#591 to - # get a newer C++ compiler toolchain. Remove this step when Cross - # 0.3.0, which includes cross-rs/cross#591, is released. - - name: Install Cross - if: "matrix.cross" - run: | - cargo install cross --git https://github.com/cross-rs/cross.git --rev 47df5c76e7cba682823a0b6aa6d95c17b31ba63a - echo "CARGO=cross" >> $GITHUB_ENV - # echo "TARGET_FLAGS=--target ${{ matrix.target }}" >> $GITHUB_ENV - # echo "TARGET_DIR=./target/${{ matrix.target }}" >> $GITHUB_ENV - - - name: Show command used for Cargo - run: | - echo "cargo command is: ${{ env.CARGO }}" - echo "target flag is: ${{ env.TARGET_FLAGS }}" - -<<<<<<< HEAD -||||||| f0f295a6 - - name: Run cargo test - uses: actions-rs/cargo@v1 - if: "!matrix.skip_tests" - with: - use-cross: ${{ matrix.cross }} - command: test - args: --release --locked --target ${{ matrix.target }} --workspace - -======= - - name: Run cargo test - if: "!matrix.skip_tests" - run: ${{ env.CARGO }} test --release --locked --target ${{ matrix.target }} --workspace - ->>>>>>> origin/master - - name: Set profile.release.strip = true - shell: bash - run: | - cat >> .cargo/config.toml < "$APP.AppDir/AppRun" - #!/bin/sh - - APPDIR="$(dirname "$(readlink -f "${0}")")" - HELIX_RUNTIME="$APPDIR/usr/lib/helix/runtime" exec "$APPDIR/usr/bin/hx" "$@" - EOF - chmod 755 "$APP.AppDir/AppRun" - - curl -Lo linuxdeploy-x86_64.AppImage \ - https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage - chmod +x linuxdeploy-x86_64.AppImage - - ./linuxdeploy-x86_64.AppImage \ - --appdir "$APP.AppDir" -d contrib/Helix.desktop \ - -i contrib/helix.png --output appimage - - mv "$APP-$VERSION-$ARCH.AppImage" \ - "$APP-$VERSION-$ARCH.AppImage.zsync" dist - - - name: Build archive - shell: bash - run: | - mkdir -p dist - if [ "${{ matrix.os }}" = "windows-2019" ]; then - cp "target/${{ matrix.target }}/release/hx.exe" "dist/" - else - cp "target/${{ matrix.target }}/release/hx" "dist/" - fi - if [ -d runtime/grammars/sources ]; then - rm -rf runtime/grammars/sources - fi - cp -r runtime dist - - - uses: actions/upload-artifact@v3 - with: - name: bins-${{ matrix.build }} - path: dist - - publish: - name: Publish - needs: [dist] - runs-on: ubuntu-latest - steps: - - name: Checkout sources - uses: actions/checkout@v3 - - - uses: actions/download-artifact@v3 - - - name: Build archive - shell: bash - run: | - set -ex - - source="$(pwd)" - mkdir -p runtime/grammars/sources - tar xJf grammars/grammars.tar.xz -C runtime/grammars/sources - rm -rf grammars - - cd "$(mktemp -d)" - mv $source/bins-* . - mkdir dist - - for dir in bins-* ; do - platform=${dir#"bins-"} - if [[ $platform =~ "windows" ]]; then - exe=".exe" - fi - pkgname=helix-$GITHUB_REF_NAME-$platform - mkdir $pkgname - cp $source/LICENSE $source/README.md $pkgname - mkdir $pkgname/contrib - cp -r $source/contrib/completion $pkgname/contrib - mv bins-$platform/runtime $pkgname/ - mv bins-$platform/hx$exe $pkgname - chmod +x $pkgname/hx$exe - - if [[ "$platform" = "aarch64-linux" || "$platform" = "x86_64-linux" ]]; then - mv bins-$platform/helix-*.AppImage* dist/ - fi - - if [ "$exe" = "" ]; then - tar cJf dist/$pkgname.tar.xz $pkgname - else - 7z a -r dist/$pkgname.zip $pkgname - fi - done - - tar cJf dist/helix-$GITHUB_REF_NAME-source.tar.xz -C $source . - mv dist $source/ - - - name: Upload binaries to release - uses: svenstaro/upload-release-action@v2 - if: env.preview == 'false' - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: dist/* - file_glob: true - tag: ${{ github.ref_name }} - overwrite: true - - - name: Upload binaries as artifact - uses: actions/upload-artifact@v3 - if: env.preview == 'true' - with: - name: release - path: dist/* diff --git a/README.md.orig b/README.md.orig deleted file mode 100644 index 3349cdb0..00000000 --- a/README.md.orig +++ /dev/null @@ -1,178 +0,0 @@ -<<<<<<< HEAD -# Helix Plus - -

This is an unstable fork of helix with some PRs merged and some merge conflicts resolved

- -# Merged PRs - -- [File explorer and tree helper](https://github.com/helix-editor/helix/pull/2377) - - [with Icons](https://github.com/r0l1/helix/tree/tree_explorer_icons) -- [Add LSP workspace command picker](https://github.com/helix-editor/helix/pull/3140) -- [completion fix](https://github.com/helix-editor/helix/pull/1819) -- [Add rainbow indentation guides](https://github.com/helix-editor/helix/pull/4056) -- [Improve sorting for inline menu (codeaction + completion)](https://github.com/helix-editor/helix/pull/4134) - -And others I forgot about... - - -# Applied Changes - -- Changed opening the window popup from `ctrl + w` to `ctrl + v` -- Added an auto highlight for files in the tree explorer when jumping through opened buffers -- Changed some default settings (enabling bufferline, indent guides, the embedded explorer, cursor modes etc.) -- Added a `--show-explorer` cli flag to open the file explorer on startup (useful for embedded explorer mode) -- Added a `delete` (aliases `rm`, `del`) command to delete the file associated with the current buffer -- Changed keybind ` E` to close the explorer instead of toggling the recursion one -- Added a completion chars setting that triggers autocomplete when typing one of those chars - -- - - -||||||| f0f295a6 -# Helix -======= -
- -

- - - - Helix - -

->>>>>>> origin/master - -[![Build status](https://github.com/helix-editor/helix/actions/workflows/build.yml/badge.svg)](https://github.com/helix-editor/helix/actions) -[![GitHub Release](https://img.shields.io/github/v/release/helix-editor/helix)](https://github.com/helix-editor/helix/releases/latest) -[![Documentation](https://shields.io/badge/-documentation-452859)](https://docs.helix-editor.com/) -[![GitHub contributors](https://img.shields.io/github/contributors/helix-editor/helix)](https://github.com/helix-editor/helix/graphs/contributors) -[![Matrix Space](https://img.shields.io/matrix/helix-community:matrix.org)](https://matrix.to/#/#helix-community:matrix.org) - -
- -![Screenshot](./screenshot.png) - -A Kakoune / Neovim inspired editor, written in Rust. - -The editing model is very heavily based on Kakoune; during development I found -myself agreeing with most of Kakoune's design decisions. - -For more information, see the [website](https://helix-editor.com) or -[documentation](https://docs.helix-editor.com/). - -All shortcuts/keymaps can be found [in the documentation on the website](https://docs.helix-editor.com/keymap.html). - -[Troubleshooting](https://github.com/helix-editor/helix/wiki/Troubleshooting) - -# Features - -- Vim-like modal editing -- Multiple selections -- Built-in language server support -- Smart, incremental syntax highlighting and code editing via tree-sitter - -It's a terminal-based editor first, but I'd like to explore a custom renderer -(similar to Emacs) in wgpu or skulpin. - -Note: Only certain languages have indentation definitions at the moment. Check -`runtime/queries//` for `indents.scm`. - -# Installation - -Packages are available for various distributions (see [Installation docs](https://docs.helix-editor.com/install.html)). - -If you would like to build from source: - -```shell -git clone https://github.com/helix-editor/helix -cd helix -cargo install --path helix-term -``` - -This will install the `hx` binary to `$HOME/.cargo/bin` and build tree-sitter grammars in `./runtime/grammars`. - -Helix needs its runtime files so make sure to copy/symlink the `runtime/` directory into the -config directory (for example `~/.config/helix/runtime` on Linux/macOS, or `%AppData%/helix/runtime` on Windows). - -| OS | Command | -| -------------------- | ------------------------------------------------ | -| Windows (Cmd) | `xcopy /e /i runtime %AppData%\helix\runtime` | -| Windows (PowerShell) | `xcopy /e /i runtime $Env:AppData\helix\runtime` | -| Linux / macOS | `ln -s $PWD/runtime ~/.config/helix/runtime` | - -Starting with Windows Vista you can also create symbolic links on Windows. Note that this requires -elevated privileges - i.e. PowerShell or Cmd must be run as administrator. - -**PowerShell:** - -```powershell -New-Item -ItemType SymbolicLink -Target "runtime" -Path "$Env:AppData\helix\runtime" -``` - -**Cmd:** - -```cmd -cd %appdata%\helix -mklink /D runtime "\runtime" -``` - -The runtime location can be overridden via the `HELIX_RUNTIME` environment variable. - -> NOTE: if `HELIX_RUNTIME` is set prior to calling `cargo install --path helix-term`, -> tree-sitter grammars will be built in `$HELIX_RUNTIME/grammars`. - -If you plan on keeping the repo locally, an alternative to copying/symlinking -runtime files is to set `HELIX_RUNTIME=/path/to/helix/runtime` -(`HELIX_RUNTIME=$PWD/runtime` if you're in the helix repo directory). - -Packages already solve this for you by wrapping the `hx` binary with a wrapper -that sets the variable to the install dir. - -> NOTE: running via cargo also doesn't require setting explicit `HELIX_RUNTIME` path, it will automatically -> detect the `runtime` directory in the project root. - -If you want to customize your `languages.toml` config, -tree-sitter grammars may be manually fetched and built with `hx --grammar fetch` and `hx --grammar build`. - -In order to use LSP features like auto-complete, you will need to -[install the appropriate Language Server](https://github.com/helix-editor/helix/wiki/How-to-install-the-default-language-servers) -for a language. - -[![Packaging status](https://repology.org/badge/vertical-allrepos/helix.svg)](https://repology.org/project/helix/versions) - -## Adding Helix to your desktop environment - -If installing from source, to use Helix in desktop environments that supports [XDG desktop menu](https://specifications.freedesktop.org/menu-spec/menu-spec-latest.html), including Gnome and KDE, copy the provided `.desktop` file to the correct folder: - -```bash -cp contrib/Helix.desktop ~/.local/share/applications -``` - -To use another terminal than the default, you will need to modify the `.desktop` file. For example, to use `kitty`: - -```bash -sed -i "s|Exec=hx %F|Exec=kitty hx %F|g" ~/.local/share/applications/Helix.desktop -sed -i "s|Terminal=true|Terminal=false|g" ~/.local/share/applications/Helix.desktop -``` - -Please note: there is no icon for Helix yet, so the system default will be used. - -## macOS - -Helix can be installed on macOS through homebrew: - -``` -brew install helix -``` - -# Contributing - -Contributing guidelines can be found [here](./docs/CONTRIBUTING.md). - -# Getting help - -Your question might already be answered on the [FAQ](https://github.com/helix-editor/helix/wiki/FAQ). - -Discuss the project on the community [Matrix Space](https://matrix.to/#/#helix-community:matrix.org) (make sure to join `#helix-editor:matrix.org` if you're on a client that doesn't support Matrix Spaces yet). - -# Credits - -Thanks to [@JakeHL](https://github.com/JakeHL) for designing the logo! diff --git a/book/src/generated/typable-cmd.md.orig b/book/src/generated/typable-cmd.md.orig deleted file mode 100644 index 9db3f8d5..00000000 --- a/book/src/generated/typable-cmd.md.orig +++ /dev/null @@ -1,84 +0,0 @@ -| Name | Description | -| --- | --- | -| `:quit`, `:q` | Close the current view. | -| `:quit!`, `:q!` | Force close the current view, ignoring unsaved changes. | -| `:open`, `:o` | Open a file from disk into the current view. | -| `:buffer-close`, `:bc`, `:bclose` | Close the current buffer. | -| `:buffer-close!`, `:bc!`, `:bclose!` | Close the current buffer forcefully, ignoring unsaved changes. | -| `:buffer-close-others`, `:bco`, `:bcloseother` | Close all buffers but the currently focused one. | -| `:buffer-close-others!`, `:bco!`, `:bcloseother!` | Force close all buffers but the currently focused one. | -| `:buffer-close-all`, `:bca`, `:bcloseall` | Close all buffers without quitting. | -| `:buffer-close-all!`, `:bca!`, `:bcloseall!` | Force close all buffers ignoring unsaved changes without quitting. | -| `:buffer-next`, `:bn`, `:bnext` | Goto next buffer. | -| `:buffer-previous`, `:bp`, `:bprev` | Goto previous buffer. | -| `:write`, `:w` | Write changes to disk. Accepts an optional path (:write some/path.txt) | -| `:write!`, `:w!` | Force write changes to disk creating necessary subdirectories. Accepts an optional path (:write some/path.txt) | -| `:new`, `:n` | Create a new scratch buffer. | -| `:format`, `:fmt` | Format the file using the LSP formatter. | -| `:indent-style` | Set the indentation style for editing. ('t' for tabs or 1-8 for number of spaces.) | -| `:line-ending` | Set the document's default line ending. Options: crlf, lf. | -| `:earlier`, `:ear` | Jump back to an earlier point in edit history. Accepts a number of steps or a time span. | -| `:later`, `:lat` | Jump to a later point in edit history. Accepts a number of steps or a time span. | -| `:write-quit`, `:wq`, `:x` | Write changes to disk and close the current view. Accepts an optional path (:wq some/path.txt) | -| `:write-quit!`, `:wq!`, `:x!` | Write changes to disk and close the current view forcefully. Accepts an optional path (:wq! some/path.txt) | -| `:write-all`, `:wa` | Write changes from all buffers to disk. | -| `:write-quit-all`, `:wqa`, `:xa` | Write changes from all buffers to disk and close all views. | -| `:write-quit-all!`, `:wqa!`, `:xa!` | Write changes from all buffers to disk and close all views forcefully (ignoring unsaved changes). | -| `:quit-all`, `:qa` | Close all views. | -| `:quit-all!`, `:qa!` | Force close all views ignoring unsaved changes. | -| `:cquit`, `:cq` | Quit with exit code (default 1). Accepts an optional integer exit code (:cq 2). | -| `:cquit!`, `:cq!` | Force quit with exit code (default 1) ignoring unsaved changes. Accepts an optional integer exit code (:cq! 2). | -| `:theme` | Change the editor theme (show current theme if no name specified). | -| `:clipboard-yank` | Yank main selection into system clipboard. | -| `:clipboard-yank-join` | Yank joined selections into system clipboard. A separator can be provided as first argument. Default value is newline. | -| `:primary-clipboard-yank` | Yank main selection into system primary clipboard. | -| `:primary-clipboard-yank-join` | Yank joined selections into system primary clipboard. A separator can be provided as first argument. Default value is newline. | -| `:clipboard-paste-after` | Paste system clipboard after selections. | -| `:clipboard-paste-before` | Paste system clipboard before selections. | -| `:clipboard-paste-replace` | Replace selections with content of system clipboard. | -| `:primary-clipboard-paste-after` | Paste primary clipboard after selections. | -| `:primary-clipboard-paste-before` | Paste primary clipboard before selections. | -| `:primary-clipboard-paste-replace` | Replace selections with content of system primary clipboard. | -| `:show-clipboard-provider` | Show clipboard provider name in status bar. | -| `:change-current-directory`, `:cd` | Change the current working directory. | -| `:show-directory`, `:pwd` | Show the current working directory. | -| `:encoding` | Set encoding. Based on `https://encoding.spec.whatwg.org`. | -| `:reload` | Discard changes and reload from the source file. | -| `:reload-all` | Discard changes and reload all documents from the source files. | -| `:update` | Write changes only if the file has been modified. | -| `:lsp-workspace-command` | Open workspace command picker | -| `:lsp-restart` | Restarts the Language Server that is in use by the current doc | -| `:tree-sitter-scopes` | Display tree sitter scopes, primarily for theming and development. | -| `:debug-start`, `:dbg` | Start a debug session from a given template with given parameters. | -| `:debug-remote`, `:dbg-tcp` | Connect to a debug adapter by TCP address and start a debugging session from a given template with given parameters. | -| `:debug-eval` | Evaluate expression in current debug context. | -| `:vsplit`, `:vs` | Open the file in a vertical split. | -| `:vsplit-new`, `:vnew` | Open a scratch buffer in a vertical split. | -| `:hsplit`, `:hs`, `:sp` | Open the file in a horizontal split. | -| `:hsplit-new`, `:hnew` | Open a scratch buffer in a horizontal split. | -| `:tutor` | Open the tutorial. | -| `:goto`, `:g` | Goto line number. | -| `:set-language`, `:lang` | Set the language of current buffer. | -| `:set-option`, `:set` | Set a config option at runtime.
For example to disable smart case search, use `:set search.smart-case false`. | -| `:get-option`, `:get` | Get the current value of a config option. | -| `:sort` | Sort ranges in selection. | -| `:rsort` | Sort ranges in selection in reverse order. | -| `:reflow` | Hard-wrap the current selection of lines to a given width. | -| `:tree-sitter-subtree`, `:ts-subtree` | Display tree sitter subtree under cursor, primarily for debugging queries. | -| `:config-reload` | Refresh user config. | -| `:config-open` | Open the user config.toml file. | -| `:log-open` | Open the helix log file. | -| `:insert-output` | Run shell command, inserting output before each selection. | -| `:append-output` | Run shell command, appending output after each selection. | -| `:pipe` | Pipe each selection to the shell command. | -<<<<<<< HEAD -<<<<<<< HEAD -||||||| f0f295a6 -======= -| `:pipe-to` | Pipe each selection to the shell command, ignoring output. | ->>>>>>> origin/master -| `:run-shell-command`, `:sh` | Run a shell command | -||||||| 4b1fe367 -======= -| `:lsp-restart` | Restarts the LSP server of the current buffer | ->>>>>>> lsp-restart diff --git a/helix-term/src/commands/lsp.rs.orig b/helix-term/src/commands/lsp.rs.orig deleted file mode 100644 index cb178ea2..00000000 --- a/helix-term/src/commands/lsp.rs.orig +++ /dev/null @@ -1,1297 +0,0 @@ -use helix_lsp::{ - block_on, - lsp::{self, CodeAction, CodeActionOrCommand, DiagnosticSeverity, NumberOrString}, - util::{diagnostic_to_lsp_diagnostic, lsp_pos_to_pos, lsp_range_to_range, range_to_lsp_range}, - OffsetEncoding, -}; -use tui::text::{Span, Spans}; - -use super::{align_view, push_jump, Align, Context, Editor, Open}; - -use helix_core::{path, Selection}; -use helix_view::{apply_transaction, document::Mode, editor::Action, theme::Style}; - -use crate::{ - compositor::{self, Compositor}, - ui::{ - self, lsp::SignatureHelp, overlay::overlayed, FileLocation, FilePicker, Popup, PromptEvent, - }, -}; - -use std::{ - borrow::Cow, cmp::Ordering, collections::BTreeMap, fmt::Write, path::PathBuf, sync::Arc, -}; - -/// Gets the language server that is attached to a document, and -/// if it's not active displays a status message. Using this macro -/// in a context where the editor automatically queries the LSP -/// (instead of when the user explicitly does so via a keybind like -/// `gd`) will spam the "LSP inactive" status message confusingly. -#[macro_export] -macro_rules! language_server { - ($editor:expr, $doc:expr) => { - match $doc.language_server() { - Some(language_server) => language_server, - None => { - $editor.set_status("Language server not active for current buffer"); - return; - } - } - }; -} - -impl ui::menu::Item for lsp::Location { - /// Current working directory. - type Data = PathBuf; - - fn label(&self, cwdir: &Self::Data) -> Spans { - // The preallocation here will overallocate a few characters since it will account for the - // URL's scheme, which is not used most of the time since that scheme will be "file://". - // Those extra chars will be used to avoid allocating when writing the line number (in the - // common case where it has 5 digits or less, which should be enough for a cast majority - // of usages). - let mut res = String::with_capacity(self.uri.as_str().len()); - - if self.uri.scheme() == "file" { - // With the preallocation above and UTF-8 paths already, this closure will do one (1) - // allocation, for `to_file_path`, else there will be two (2), with `to_string_lossy`. - let mut write_path_to_res = || -> Option<()> { - let path = self.uri.to_file_path().ok()?; - res.push_str(&path.strip_prefix(cwdir).unwrap_or(&path).to_string_lossy()); - Some(()) - }; - write_path_to_res(); - } else { - // Never allocates since we declared the string with this capacity already. - res.push_str(self.uri.as_str()); - } - - // Most commonly, this will not allocate, especially on Unix systems where the root prefix - // is a simple `/` and not `C:\` (with whatever drive letter) - write!(&mut res, ":{}", self.range.start.line) - .expect("Will only failed if allocating fail"); - res.into() - } -} - -impl ui::menu::Item for lsp::SymbolInformation { - /// Path to currently focussed document - type Data = Option; - - fn label(&self, current_doc_path: &Self::Data) -> Spans { - if current_doc_path.as_ref() == Some(&self.location.uri) { - self.name.as_str().into() - } else { - match self.location.uri.to_file_path() { - Ok(path) => { - let get_relative_path = path::get_relative_path(path.as_path()); - format!("{} ({})", &self.name, get_relative_path.to_string_lossy()).into() - } - Err(_) => format!("{} ({})", &self.name, &self.location.uri).into(), - } - } - } -} - -struct DiagnosticStyles { - hint: Style, - info: Style, - warning: Style, - error: Style, -} - -struct PickerDiagnostic { - url: lsp::Url, - diag: lsp::Diagnostic, -} - -impl ui::menu::Item for PickerDiagnostic { - type Data = (DiagnosticStyles, DiagnosticsFormat); - - fn label(&self, (styles, format): &Self::Data) -> Spans { - let mut style = self - .diag - .severity - .map(|s| match s { - DiagnosticSeverity::HINT => styles.hint, - DiagnosticSeverity::INFORMATION => styles.info, - DiagnosticSeverity::WARNING => styles.warning, - DiagnosticSeverity::ERROR => styles.error, - _ => Style::default(), - }) - .unwrap_or_default(); - - // remove background as it is distracting in the picker list - style.bg = None; - - let code: Cow<'_, str> = self - .diag - .code - .as_ref() - .map(|c| match c { - NumberOrString::Number(n) => n.to_string().into(), - NumberOrString::String(s) => s.as_str().into(), - }) - .unwrap_or_default(); - - let path = match format { - DiagnosticsFormat::HideSourcePath => String::new(), - DiagnosticsFormat::ShowSourcePath => { - let path = path::get_truncated_path(self.url.path()); - format!("{}: ", path.to_string_lossy()) - } - }; - - Spans::from(vec![ - Span::raw(path), - Span::styled(&self.diag.message, style), - Span::styled(code, style), - ]) - } -} - -fn location_to_file_location(location: &lsp::Location) -> FileLocation { - let path = location.uri.to_file_path().unwrap(); - let line = Some(( - location.range.start.line as usize, - location.range.end.line as usize, - )); - (path.into(), line) -} - -// TODO: share with symbol picker(symbol.location) -fn jump_to_location( - editor: &mut Editor, - location: &lsp::Location, - offset_encoding: OffsetEncoding, - action: Action, -) { - let (view, doc) = current!(editor); - push_jump(view, doc); - - let path = match location.uri.to_file_path() { - Ok(path) => path, - Err(_) => { - let err = format!("unable to convert URI to filepath: {}", location.uri); - editor.set_error(err); - return; - } - }; - match editor.open(&path, action) { - Ok(_) => (), - Err(err) => { - let err = format!("failed to open path: {:?}: {:?}", location.uri, err); - editor.set_error(err); - return; - } - } - let (view, doc) = current!(editor); - let definition_pos = location.range.start; - // TODO: convert inside server - let new_pos = if let Some(new_pos) = lsp_pos_to_pos(doc.text(), definition_pos, offset_encoding) - { - new_pos - } else { - return; - }; - doc.set_selection(view.id, Selection::point(new_pos)); - align_view(doc, view, Align::Center); -} - -fn sym_picker( - symbols: Vec, - current_path: Option, - offset_encoding: OffsetEncoding, -) -> FilePicker { - // TODO: drop current_path comparison and instead use workspace: bool flag? - FilePicker::new( - symbols, - current_path.clone(), - move |cx, symbol, action| { - let (view, doc) = current!(cx.editor); - push_jump(view, doc); - - if current_path.as_ref() != Some(&symbol.location.uri) { - let uri = &symbol.location.uri; - let path = match uri.to_file_path() { - Ok(path) => path, - Err(_) => { - let err = format!("unable to convert URI to filepath: {}", uri); - cx.editor.set_error(err); - return; - } - }; - if let Err(err) = cx.editor.open(&path, action) { - let err = format!("failed to open document: {}: {}", uri, err); - log::error!("{}", err); - cx.editor.set_error(err); - return; - } - } - - let (view, doc) = current!(cx.editor); - - if let Some(range) = - lsp_range_to_range(doc.text(), symbol.location.range, offset_encoding) - { - // we flip the range so that the cursor sits on the start of the symbol - // (for example start of the function). - doc.set_selection(view.id, Selection::single(range.head, range.anchor)); - align_view(doc, view, Align::Center); - } - }, - move |_editor, symbol| Some(location_to_file_location(&symbol.location)), - ) - .truncate_start(false) -} - -#[derive(Copy, Clone, PartialEq)] -enum DiagnosticsFormat { - ShowSourcePath, - HideSourcePath, -} - -fn diag_picker( - cx: &Context, - diagnostics: BTreeMap>, - current_path: Option, - format: DiagnosticsFormat, - offset_encoding: OffsetEncoding, -) -> FilePicker { - // TODO: drop current_path comparison and instead use workspace: bool flag? - - // flatten the map to a vec of (url, diag) pairs - let mut flat_diag = Vec::new(); - for (url, diags) in diagnostics { - flat_diag.reserve(diags.len()); - for diag in diags { - flat_diag.push(PickerDiagnostic { - url: url.clone(), - diag, - }); - } - } - - let styles = DiagnosticStyles { - hint: cx.editor.theme.get("hint"), - info: cx.editor.theme.get("info"), - warning: cx.editor.theme.get("warning"), - error: cx.editor.theme.get("error"), - }; - - FilePicker::new( - flat_diag, - (styles, format), - move |cx, PickerDiagnostic { url, diag }, action| { - if current_path.as_ref() == Some(url) { - let (view, doc) = current!(cx.editor); - push_jump(view, doc); - } else { - let path = url.to_file_path().unwrap(); - cx.editor.open(&path, action).expect("editor.open failed"); - } - - let (view, doc) = current!(cx.editor); - - if let Some(range) = lsp_range_to_range(doc.text(), diag.range, offset_encoding) { - // we flip the range so that the cursor sits on the start of the symbol - // (for example start of the function). - doc.set_selection(view.id, Selection::single(range.head, range.anchor)); - align_view(doc, view, Align::Center); - } - }, - move |_editor, PickerDiagnostic { url, diag }| { - let location = lsp::Location::new(url.clone(), diag.range); - Some(location_to_file_location(&location)) - }, - ) - .truncate_start(false) -} - -pub fn symbol_picker(cx: &mut Context) { - fn nested_to_flat( - list: &mut Vec, - file: &lsp::TextDocumentIdentifier, - symbol: lsp::DocumentSymbol, - ) { - #[allow(deprecated)] - list.push(lsp::SymbolInformation { - name: symbol.name, - kind: symbol.kind, - tags: symbol.tags, - deprecated: symbol.deprecated, - location: lsp::Location::new(file.uri.clone(), symbol.selection_range), - container_name: None, - }); - for child in symbol.children.into_iter().flatten() { - nested_to_flat(list, file, child); - } - } - let doc = doc!(cx.editor); - - let language_server = language_server!(cx.editor, doc); - let current_url = doc.url(); - let offset_encoding = language_server.offset_encoding(); - - let future = match language_server.document_symbols(doc.identifier()) { - Some(future) => future, - None => { - cx.editor - .set_error("Language server does not support document symbols"); - return; - } - }; - - cx.callback( - future, - move |editor, compositor, response: Option| { - if let Some(symbols) = response { - // lsp has two ways to represent symbols (flat/nested) - // convert the nested variant to flat, so that we have a homogeneous list - let symbols = match symbols { - lsp::DocumentSymbolResponse::Flat(symbols) => symbols, - lsp::DocumentSymbolResponse::Nested(symbols) => { - let doc = doc!(editor); - let mut flat_symbols = Vec::new(); - for symbol in symbols { - nested_to_flat(&mut flat_symbols, &doc.identifier(), symbol) - } - flat_symbols - } - }; - - let picker = sym_picker(symbols, current_url, offset_encoding); - compositor.push(Box::new(overlayed(picker))) - } - }, - ) -} - -pub fn workspace_symbol_picker(cx: &mut Context) { - let doc = doc!(cx.editor); - let current_url = doc.url(); - let language_server = language_server!(cx.editor, doc); - let offset_encoding = language_server.offset_encoding(); - let future = match language_server.workspace_symbols("".to_string()) { - Some(future) => future, - None => { - cx.editor - .set_error("Language server does not support workspace symbols"); - return; - } - }; - - cx.callback( - future, - move |_editor, compositor, response: Option>| { - if let Some(symbols) = response { - let picker = sym_picker(symbols, current_url, offset_encoding); - compositor.push(Box::new(overlayed(picker))) - } - }, - ) -} - -pub fn diagnostics_picker(cx: &mut Context) { - let doc = doc!(cx.editor); - let language_server = language_server!(cx.editor, doc); - if let Some(current_url) = doc.url() { - let offset_encoding = language_server.offset_encoding(); - let diagnostics = cx - .editor - .diagnostics - .get(¤t_url) - .cloned() - .unwrap_or_default(); - let picker = diag_picker( - cx, - [(current_url.clone(), diagnostics)].into(), - Some(current_url), - DiagnosticsFormat::HideSourcePath, - offset_encoding, - ); - cx.push_layer(Box::new(overlayed(picker))); - } -} - -pub fn workspace_diagnostics_picker(cx: &mut Context) { - let doc = doc!(cx.editor); - let language_server = language_server!(cx.editor, doc); - let current_url = doc.url(); - let offset_encoding = language_server.offset_encoding(); - let diagnostics = cx.editor.diagnostics.clone(); - let picker = diag_picker( - cx, - diagnostics, - current_url, - DiagnosticsFormat::ShowSourcePath, - offset_encoding, - ); - cx.push_layer(Box::new(overlayed(picker))); -} - -impl ui::menu::Item for lsp::CodeActionOrCommand { - type Data = (); - fn label(&self, _data: &Self::Data) -> Spans { - match self { - lsp::CodeActionOrCommand::CodeAction(action) => action.title.as_str().into(), - lsp::CodeActionOrCommand::Command(command) => command.title.as_str().into(), - } - } -} - -/// Determines the category of the `CodeAction` using the `CodeAction::kind` field. -/// Returns a number that represent these categories. -/// Categories with a lower number should be displayed first. -/// -/// -/// While the `kind` field is defined as open ended in the LSP spec (any value may be used) -/// in practice a closed set of common values (mostly suggested in the LSP spec) are used. -/// VSCode displays each of these categories seperatly (seperated by a heading in the codeactions picker) -/// to make them easier to navigate. Helix does not display these headings to the user. -/// However it does sort code actions by their categories to achieve the same order as the VScode picker, -/// just without the headings. -/// -/// The order used here is modeled after the [vscode sourcecode](https://github.com/microsoft/vscode/blob/eaec601dd69aeb4abb63b9601a6f44308c8d8c6e/src/vs/editor/contrib/codeAction/browser/codeActionWidget.ts>) -fn action_category(action: &CodeActionOrCommand) -> u32 { - if let CodeActionOrCommand::CodeAction(CodeAction { - kind: Some(kind), .. - }) = action - { - let mut components = kind.as_str().split('.'); - match components.next() { - Some("quickfix") => 0, - Some("refactor") => match components.next() { - Some("extract") => 1, - Some("inline") => 2, - Some("rewrite") => 3, - Some("move") => 4, - Some("surround") => 5, - _ => 7, - }, - Some("source") => 6, - _ => 7, - } - } else { - 7 - } -} - -fn action_prefered(action: &CodeActionOrCommand) -> bool { - matches!( - action, - CodeActionOrCommand::CodeAction(CodeAction { - is_preferred: Some(true), - .. - }) - ) -} - -fn action_fixes_diagnostics(action: &CodeActionOrCommand) -> bool { - matches!( - action, - CodeActionOrCommand::CodeAction(CodeAction { - diagnostics: Some(diagnostics), - .. - }) if !diagnostics.is_empty() - ) -} - -pub fn code_action(cx: &mut Context) { - let (view, doc) = current!(cx.editor); - - let language_server = language_server!(cx.editor, doc); - - let selection_range = doc.selection(view.id).primary(); - let offset_encoding = language_server.offset_encoding(); - - let range = range_to_lsp_range(doc.text(), selection_range, offset_encoding); - - let future = match language_server.code_actions( - doc.identifier(), - range, - // Filter and convert overlapping diagnostics - lsp::CodeActionContext { - diagnostics: doc - .diagnostics() - .iter() - .filter(|&diag| { - selection_range - .overlaps(&helix_core::Range::new(diag.range.start, diag.range.end)) - }) - .map(|diag| diagnostic_to_lsp_diagnostic(doc.text(), diag, offset_encoding)) - .collect(), - only: None, - }, - ) { - Some(future) => future, - None => { - cx.editor - .set_error("Language server does not support code actions"); - return; - } - }; - - cx.callback( - future, - move |editor, compositor, response: Option| { - let mut actions = match response { - Some(a) => a, - None => return, - }; - - // remove disabled code actions - actions.retain(|action| { - matches!( - action, - CodeActionOrCommand::Command(_) - | CodeActionOrCommand::CodeAction(CodeAction { disabled: None, .. }) - ) - }); - - if actions.is_empty() { - editor.set_status("No code actions available"); - return; - } - - // Sort codeactions into a useful order. This behaviour is only partially described in the LSP spec. - // VScode sorts the codeaction two times: - // - // First the codeactions that fix some diagnostics are moved to the front. - // If both codeactions fix some diagnostics (or both fix none) the codeaction - // that is marked with `is_preffered` is shown first. The codeactions are then shown in seperate - // submenus that only contain a certain category (see `action_category`) of actions. - // - // Below this done in in a single sorting step - actions.sort_by(|action1, action2| { - // sort actions by category - let order = action_category(action1).cmp(&action_category(action2)); - if order != Ordering::Equal { - return order; - } - // within the categories sort by relevancy. - // Modeled after the `codeActionsComparator` function in vscode: - // https://github.com/microsoft/vscode/blob/eaec601dd69aeb4abb63b9601a6f44308c8d8c6e/src/vs/editor/contrib/codeAction/browser/codeAction.ts - - // if one code action fixes a diagnostic but the other one doesn't show it first - let order = action_fixes_diagnostics(action1) - .cmp(&action_fixes_diagnostics(action2)) - .reverse(); - if order != Ordering::Equal { - return order; - } - - // if one of the codeactions is marked as prefered show it first - // otherwise keep the original LSP sorting - action_prefered(action1) - .cmp(&action_prefered(action2)) - .reverse() - }); - - let mut picker = - ui::Menu::new(actions, false, (), move |editor, code_action, event| { - if event != PromptEvent::Validate { - return; - } - - // always present here - let code_action = code_action.unwrap(); - - match code_action { - lsp::CodeActionOrCommand::Command(command) => { - log::debug!("code action command: {:?}", command); - execute_lsp_command(editor, command.clone()); - } - lsp::CodeActionOrCommand::CodeAction(code_action) => { - log::debug!("code action: {:?}", code_action); - if let Some(ref workspace_edit) = code_action.edit { - log::debug!("edit: {:?}", workspace_edit); - apply_workspace_edit(editor, offset_encoding, workspace_edit); - } - - // if code action provides both edit and command first the edit - // should be applied and then the command - if let Some(command) = &code_action.command { - execute_lsp_command(editor, command.clone()); - } - } - } - }); - picker.move_down(); // pre-select the first item - - let popup = Popup::new("code-action", picker).with_scrollbar(false); - compositor.replace_or_push("code-action", popup); - }, - ) -} -<<<<<<< HEAD - -impl ui::menu::Item for lsp::Command { - type Data = (); - fn label(&self, _data: &Self::Data) -> Spans { - self.title.as_str().into() - } -} - -pub fn workspace_command_picker(cx: &mut Context) { - let (_, doc) = current!(cx.editor); - - let language_server = language_server!(cx.editor, doc); - - let execute_command_provider = match &language_server.capabilities().execute_command_provider { - Some(p) => p, - None => return, - }; - let commands = execute_command_provider - .commands - .iter() - .map(|command| lsp::Command { - title: command.clone(), - command: command.clone(), - arguments: None, - }) - .collect::>(); - cx.callback = Some(Box::new( - move |compositor: &mut Compositor, _cx: &mut compositor::Context| { - let picker = ui::Picker::new(commands, (), move |cx, command, _action| { - execute_lsp_command(cx.editor, command.clone()); - }); - compositor.push(Box::new(overlayed(picker))) - }, - )); -} - -||||||| 4ec2a21c -======= - -impl ui::menu::Item for lsp::Command { - type Data = (); - fn label(&self, _data: &Self::Data) -> Spans { - self.title.as_str().into() - } -} - ->>>>>>> master -pub fn execute_lsp_command(editor: &mut Editor, cmd: lsp::Command) { - let doc = doc!(editor); - let language_server = language_server!(editor, doc); - - // the command is executed on the server and communicated back - // to the client asynchronously using workspace edits - let future = match language_server.command(cmd) { - Some(future) => future, - None => { - editor.set_error("Language server does not support executing commands"); - return; - } - }; - - tokio::spawn(async move { - let res = future.await; - - if let Err(e) = res { - log::error!("execute LSP command: {}", e); - } - }); -} - -pub fn apply_document_resource_op(op: &lsp::ResourceOp) -> std::io::Result<()> { - use lsp::ResourceOp; - use std::fs; - match op { - ResourceOp::Create(op) => { - let path = op.uri.to_file_path().unwrap(); - let ignore_if_exists = op.options.as_ref().map_or(false, |options| { - !options.overwrite.unwrap_or(false) && options.ignore_if_exists.unwrap_or(false) - }); - if ignore_if_exists && path.exists() { - Ok(()) - } else { - // Create directory if it does not exist - if let Some(dir) = path.parent() { - if !dir.is_dir() { - fs::create_dir_all(dir)?; - } - } - - fs::write(&path, []) - } - } - ResourceOp::Delete(op) => { - let path = op.uri.to_file_path().unwrap(); - if path.is_dir() { - let recursive = op - .options - .as_ref() - .and_then(|options| options.recursive) - .unwrap_or(false); - - if recursive { - fs::remove_dir_all(&path) - } else { - fs::remove_dir(&path) - } - } else if path.is_file() { - fs::remove_file(&path) - } else { - Ok(()) - } - } - ResourceOp::Rename(op) => { - let from = op.old_uri.to_file_path().unwrap(); - let to = op.new_uri.to_file_path().unwrap(); - let ignore_if_exists = op.options.as_ref().map_or(false, |options| { - !options.overwrite.unwrap_or(false) && options.ignore_if_exists.unwrap_or(false) - }); - if ignore_if_exists && to.exists() { - Ok(()) - } else { - fs::rename(&from, &to) - } - } - } -} - -pub fn apply_workspace_edit( - editor: &mut Editor, - offset_encoding: OffsetEncoding, - workspace_edit: &lsp::WorkspaceEdit, -) { - let mut apply_edits = |uri: &helix_lsp::Url, text_edits: Vec| { - let path = match uri.to_file_path() { - Ok(path) => path, - Err(_) => { - let err = format!("unable to convert URI to filepath: {}", uri); - log::error!("{}", err); - editor.set_error(err); - return; - } - }; - - let current_view_id = view!(editor).id; - let doc_id = match editor.open(&path, Action::Load) { - Ok(doc_id) => doc_id, - Err(err) => { - let err = format!("failed to open document: {}: {}", uri, err); - log::error!("{}", err); - editor.set_error(err); - return; - } - }; - - let doc = doc_mut!(editor, &doc_id); - - // Need to determine a view for apply/append_changes_to_history - let selections = doc.selections(); - let view_id = if selections.contains_key(¤t_view_id) { - // use current if possible - current_view_id - } else { - // Hack: we take the first available view_id - selections - .keys() - .next() - .copied() - .expect("No view_id available") - }; - - let transaction = helix_lsp::util::generate_transaction_from_edits( - doc.text(), - text_edits, - offset_encoding, - ); - apply_transaction(&transaction, doc, view_mut!(editor, view_id)); - doc.append_changes_to_history(view_id); - }; - - if let Some(ref changes) = workspace_edit.changes { - log::debug!("workspace changes: {:?}", changes); - for (uri, text_edits) in changes { - let text_edits = text_edits.to_vec(); - apply_edits(uri, text_edits) - } - return; - // Not sure if it works properly, it'll be safer to just panic here to avoid breaking some parts of code on which code actions will be used - // TODO: find some example that uses workspace changes, and test it - // for (url, edits) in changes.iter() { - // let file_path = url.origin().ascii_serialization(); - // let file_path = std::path::PathBuf::from(file_path); - // let file = std::fs::File::open(file_path).unwrap(); - // let mut text = Rope::from_reader(file).unwrap(); - // let transaction = edits_to_changes(&text, edits); - // transaction.apply(&mut text); - // } - } - - if let Some(ref document_changes) = workspace_edit.document_changes { - match document_changes { - lsp::DocumentChanges::Edits(document_edits) => { - for document_edit in document_edits { - let edits = document_edit - .edits - .iter() - .map(|edit| match edit { - lsp::OneOf::Left(text_edit) => text_edit, - lsp::OneOf::Right(annotated_text_edit) => { - &annotated_text_edit.text_edit - } - }) - .cloned() - .collect(); - apply_edits(&document_edit.text_document.uri, edits); - } - } - lsp::DocumentChanges::Operations(operations) => { - log::debug!("document changes - operations: {:?}", operations); - for operation in operations { - match operation { - lsp::DocumentChangeOperation::Op(op) => { - apply_document_resource_op(op).unwrap(); - } - - lsp::DocumentChangeOperation::Edit(document_edit) => { - let edits = document_edit - .edits - .iter() - .map(|edit| match edit { - lsp::OneOf::Left(text_edit) => text_edit, - lsp::OneOf::Right(annotated_text_edit) => { - &annotated_text_edit.text_edit - } - }) - .cloned() - .collect(); - apply_edits(&document_edit.text_document.uri, edits); - } - } - } - } - } - } -} - -fn goto_impl( - editor: &mut Editor, - compositor: &mut Compositor, - locations: Vec, - offset_encoding: OffsetEncoding, -) { - let cwdir = std::env::current_dir().unwrap_or_default(); - - match locations.as_slice() { - [location] => { - jump_to_location(editor, location, offset_encoding, Action::Replace); - } - [] => { - editor.set_error("No definition found."); - } - _locations => { - let picker = FilePicker::new( - locations, - cwdir, - move |cx, location, action| { - jump_to_location(cx.editor, location, offset_encoding, action) - }, - move |_editor, location| Some(location_to_file_location(location)), - ); - compositor.push(Box::new(overlayed(picker))); - } - } -} - -fn to_locations(definitions: Option) -> Vec { - match definitions { - Some(lsp::GotoDefinitionResponse::Scalar(location)) => vec![location], - Some(lsp::GotoDefinitionResponse::Array(locations)) => locations, - Some(lsp::GotoDefinitionResponse::Link(locations)) => locations - .into_iter() - .map(|location_link| lsp::Location { - uri: location_link.target_uri, - range: location_link.target_range, - }) - .collect(), - None => Vec::new(), - } -} - -pub fn goto_definition(cx: &mut Context) { - let (view, doc) = current!(cx.editor); - let language_server = language_server!(cx.editor, doc); - let offset_encoding = language_server.offset_encoding(); - - let pos = doc.position(view.id, offset_encoding); - - let future = match language_server.goto_definition(doc.identifier(), pos, None) { - Some(future) => future, - None => { - cx.editor - .set_error("Language server does not support goto-definition"); - return; - } - }; - - cx.callback( - future, - move |editor, compositor, response: Option| { - let items = to_locations(response); - goto_impl(editor, compositor, items, offset_encoding); - }, - ); -} - -pub fn goto_type_definition(cx: &mut Context) { - let (view, doc) = current!(cx.editor); - let language_server = language_server!(cx.editor, doc); - let offset_encoding = language_server.offset_encoding(); - - let pos = doc.position(view.id, offset_encoding); - - let future = match language_server.goto_type_definition(doc.identifier(), pos, None) { - Some(future) => future, - None => { - cx.editor - .set_error("Language server does not support goto-type-definition"); - return; - } - }; - - cx.callback( - future, - move |editor, compositor, response: Option| { - let items = to_locations(response); - goto_impl(editor, compositor, items, offset_encoding); - }, - ); -} - -pub fn goto_implementation(cx: &mut Context) { - let (view, doc) = current!(cx.editor); - let language_server = language_server!(cx.editor, doc); - let offset_encoding = language_server.offset_encoding(); - - let pos = doc.position(view.id, offset_encoding); - - let future = match language_server.goto_implementation(doc.identifier(), pos, None) { - Some(future) => future, - None => { - cx.editor - .set_error("Language server does not support goto-implementation"); - return; - } - }; - - cx.callback( - future, - move |editor, compositor, response: Option| { - let items = to_locations(response); - goto_impl(editor, compositor, items, offset_encoding); - }, - ); -} - -pub fn goto_reference(cx: &mut Context) { - let (view, doc) = current!(cx.editor); - let language_server = language_server!(cx.editor, doc); - let offset_encoding = language_server.offset_encoding(); - - let pos = doc.position(view.id, offset_encoding); - - let future = match language_server.goto_reference(doc.identifier(), pos, None) { - Some(future) => future, - None => { - cx.editor - .set_error("Language server does not support goto-reference"); - return; - } - }; - - cx.callback( - future, - move |editor, compositor, response: Option>| { - let items = response.unwrap_or_default(); - goto_impl(editor, compositor, items, offset_encoding); - }, - ); -} - -#[derive(PartialEq, Eq)] -pub enum SignatureHelpInvoked { - Manual, - Automatic, -} - -pub fn signature_help(cx: &mut Context) { - signature_help_impl(cx, SignatureHelpInvoked::Manual) -} - -pub fn signature_help_impl(cx: &mut Context, invoked: SignatureHelpInvoked) { - let (view, doc) = current!(cx.editor); - let was_manually_invoked = invoked == SignatureHelpInvoked::Manual; - - let language_server = match doc.language_server() { - Some(language_server) => language_server, - None => { - // Do not show the message if signature help was invoked - // automatically on backspace, trigger characters, etc. - if was_manually_invoked { - cx.editor - .set_status("Language server not active for current buffer"); - } - return; - } - }; - let offset_encoding = language_server.offset_encoding(); - - let pos = doc.position(view.id, offset_encoding); - - let future = match language_server.text_document_signature_help(doc.identifier(), pos, None) { - Some(f) => f, - None => { - if was_manually_invoked { - cx.editor - .set_error("Language server does not support signature-help"); - } - return; - } - }; - - cx.callback( - future, - move |editor, compositor, response: Option| { - let config = &editor.config(); - - if !(config.lsp.auto_signature_help - || SignatureHelp::visible_popup(compositor).is_some() - || was_manually_invoked) - { - return; - } - - // If the signature help invocation is automatic, don't show it outside of Insert Mode: - // it very probably means the server was a little slow to respond and the user has - // already moved on to something else, making a signature help popup will just be an - // annoyance, see https://github.com/helix-editor/helix/issues/3112 - if !was_manually_invoked && editor.mode != Mode::Insert { - return; - } - - let response = match response { - // According to the spec the response should be None if there - // are no signatures, but some servers don't follow this. - Some(s) if !s.signatures.is_empty() => s, - _ => { - compositor.remove(SignatureHelp::ID); - return; - } - }; - let doc = doc!(editor); - let language = doc.language_name().unwrap_or(""); - - let signature = match response - .signatures - .get(response.active_signature.unwrap_or(0) as usize) - { - Some(s) => s, - None => return, - }; - let mut contents = SignatureHelp::new( - signature.label.clone(), - language.to_string(), - Arc::clone(&editor.syn_loader), - ); - - let signature_doc = if config.lsp.display_signature_help_docs { - signature.documentation.as_ref().map(|doc| match doc { - lsp::Documentation::String(s) => s.clone(), - lsp::Documentation::MarkupContent(markup) => markup.value.clone(), - }) - } else { - None - }; - - contents.set_signature_doc(signature_doc); - - let active_param_range = || -> Option<(usize, usize)> { - let param_idx = signature - .active_parameter - .or(response.active_parameter) - .unwrap_or(0) as usize; - let param = signature.parameters.as_ref()?.get(param_idx)?; - match ¶m.label { - lsp::ParameterLabel::Simple(string) => { - let start = signature.label.find(string.as_str())?; - Some((start, start + string.len())) - } - lsp::ParameterLabel::LabelOffsets([start, end]) => { - // LS sends offsets based on utf-16 based string representation - // but highlighting in helix is done using byte offset. - use helix_core::str_utils::char_to_byte_idx; - let from = char_to_byte_idx(&signature.label, *start as usize); - let to = char_to_byte_idx(&signature.label, *end as usize); - Some((from, to)) - } - } - }; - contents.set_active_param_range(active_param_range()); - - let old_popup = compositor.find_id::>(SignatureHelp::ID); - let popup = Popup::new(SignatureHelp::ID, contents) - .position(old_popup.and_then(|p| p.get_position())) - .position_bias(Open::Above) - .ignore_escape_key(true); - compositor.replace_or_push(SignatureHelp::ID, popup); - }, - ); -} - -pub fn hover(cx: &mut Context) { - let (view, doc) = current!(cx.editor); - let language_server = language_server!(cx.editor, doc); - let offset_encoding = language_server.offset_encoding(); - - // TODO: factor out a doc.position_identifier() that returns lsp::TextDocumentPositionIdentifier - - let pos = doc.position(view.id, offset_encoding); - - let future = match language_server.text_document_hover(doc.identifier(), pos, None) { - Some(future) => future, - None => { - cx.editor - .set_error("Language server does not support hover"); - return; - } - }; - - cx.callback( - future, - move |editor, compositor, response: Option| { - if let Some(hover) = response { - // hover.contents / .range <- used for visualizing - - fn marked_string_to_markdown(contents: lsp::MarkedString) -> String { - match contents { - lsp::MarkedString::String(contents) => contents, - lsp::MarkedString::LanguageString(string) => { - if string.language == "markdown" { - string.value - } else { - format!("```{}\n{}\n```", string.language, string.value) - } - } - } - } - - let contents = match hover.contents { - lsp::HoverContents::Scalar(contents) => marked_string_to_markdown(contents), - lsp::HoverContents::Array(contents) => contents - .into_iter() - .map(marked_string_to_markdown) - .collect::>() - .join("\n\n"), - lsp::HoverContents::Markup(contents) => contents.value, - }; - - // skip if contents empty - - let contents = ui::Markdown::new(contents, editor.syn_loader.clone()); - let popup = Popup::new("hover", contents).auto_close(true); - compositor.replace_or_push("hover", popup); - } - }, - ); -} - -pub fn rename_symbol(cx: &mut Context) { - let (view, doc) = current_ref!(cx.editor); - let text = doc.text().slice(..); - let primary_selection = doc.selection(view.id).primary(); - let prefill = if primary_selection.len() > 1 { - primary_selection - } else { - use helix_core::textobject::{textobject_word, TextObject}; - textobject_word(text, primary_selection, TextObject::Inside, 1, false) - } - .fragment(text) - .into(); - ui::prompt_with_input( - cx, - "rename-to:".into(), - prefill, - None, - ui::completers::none, - move |cx: &mut compositor::Context, input: &str, event: PromptEvent| { - if event != PromptEvent::Validate { - return; - } - - let (view, doc) = current!(cx.editor); - let language_server = language_server!(cx.editor, doc); - let offset_encoding = language_server.offset_encoding(); - - let pos = doc.position(view.id, offset_encoding); - - let future = - match language_server.rename_symbol(doc.identifier(), pos, input.to_string()) { - Some(future) => future, - None => { - cx.editor - .set_error("Language server does not support symbol renaming"); - return; - } - }; - match block_on(future) { - Ok(edits) => apply_workspace_edit(cx.editor, offset_encoding, &edits), - Err(err) => cx.editor.set_error(err.to_string()), - } - }, - ); -} - -pub fn select_references_to_symbol_under_cursor(cx: &mut Context) { - let (view, doc) = current!(cx.editor); - let language_server = language_server!(cx.editor, doc); - let offset_encoding = language_server.offset_encoding(); - - let pos = doc.position(view.id, offset_encoding); - - let future = match language_server.text_document_document_highlight(doc.identifier(), pos, None) - { - Some(future) => future, - None => { - cx.editor - .set_error("Language server does not support document highlight"); - return; - } - }; - - cx.callback( - future, - move |editor, _compositor, response: Option>| { - let document_highlights = match response { - Some(highlights) if !highlights.is_empty() => highlights, - _ => return, - }; - let (view, doc) = current!(editor); - let language_server = language_server!(editor, doc); - let offset_encoding = language_server.offset_encoding(); - let text = doc.text(); - let pos = doc.selection(view.id).primary().head; - - // We must find the range that contains our primary cursor to prevent our primary cursor to move - let mut primary_index = 0; - let ranges = document_highlights - .iter() - .filter_map(|highlight| lsp_range_to_range(text, highlight.range, offset_encoding)) - .enumerate() - .map(|(i, range)| { - if range.contains(pos) { - primary_index = i; - } - range - }) - .collect(); - let selection = Selection::new(ranges, primary_index); - doc.set_selection(view.id, selection); - }, - ); -} diff --git a/runtime/themes/dracula.toml.orig b/runtime/themes/dracula.toml.orig deleted file mode 100644 index f0490fb8..00000000 --- a/runtime/themes/dracula.toml.orig +++ /dev/null @@ -1,84 +0,0 @@ -# Author : Sebastian Zivota -"comment" = { fg = "comment" } -"constant" = { fg = "purple" } -"constant.character.escape" = { fg = "pink" } -"function" = { fg = "green" } -"keyword" = { fg = "pink" } -"operator" = { fg = "pink" } -"punctuation" = { fg = "foreground" } -"string" = { fg = "yellow" } -"string.regexp" = { fg = "red" } -"tag" = { fg = "pink" } -"type" = { fg = "cyan", modifiers = ["italic"] } -"type.enum.variant" = { fg = "foreground", modifiers = ["italic"] } -"variable" = { fg = "foreground" } -"variable.builtin" = { fg = "cyan", modifiers = ["italic"] } -"variable.parameter" = { fg ="orange", modifiers = ["italic"] } - -"diff.plus" = { fg = "green" } -"diff.delta" = { fg = "orange" } -"diff.minus" = { fg = "red" } - -"ui.background" = { fg = "foreground", bg = "background" } -"ui.cursor" = { fg = "background", bg = "orange", modifiers = ["dim"] } -"ui.cursor.match" = { fg = "green", modifiers = ["underlined"] } -"ui.cursor.primary" = { fg = "background", bg = "cyan", modifiers = ["dim"] } -"ui.cursorline.primary" = { bg = "background_dark" } -"ui.help" = { fg = "foreground", bg = "background_dark" } -"ui.linenr" = { fg = "comment" } -"ui.linenr.selected" = { fg = "foreground" } -"ui.menu" = { fg = "foreground", bg = "background_dark" } -"ui.menu.selected" = { fg = "cyan", bg = "background_dark" } -"ui.popup" = { fg = "foreground", bg = "background_dark" } -"ui.selection" = { bg = "secondary_highlight" } -"ui.selection.primary" = { bg = "primary_highlight" } -"ui.statusline" = { fg = "foreground", bg = "background_dark" } -"ui.statusline.inactive" = { fg = "comment", bg = "background_dark" } -"ui.statusline.normal" = { fg = "background_dark", bg = "cyan" } -"ui.statusline.insert" = { fg = "background_dark", bg = "green" } -"ui.statusline.select" = { fg = "background_dark", bg = "purple" } -"ui.text" = { fg = "foreground" } -"ui.text.focus" = { fg = "cyan" } -"ui.window" = { fg = "foreground" } -"ui.virtual.whitespace" = { fg = "comment" } -"ui.virtual.ruler" = { bg = "background_dark"} - -"error" = { fg = "red" } -"warning" = { fg = "cyan" } - -"markup.heading" = { fg = "purple", modifiers = ["bold"] } -"markup.list" = "cyan" -"markup.bold" = { fg = "orange", modifiers = ["bold"] } -"markup.italic" = { fg = "yellow", modifiers = ["italic"] } -"markup.link.url" = "cyan" -"markup.link.text" = "pink" -"markup.quote" = { fg = "yellow", modifiers = ["italic"] } -"markup.raw" = { fg = "foreground" } - -<<<<<<< HEAD -"ui.explorer.file" = { fg = "foreground" } -"ui.explorer.dir" = { fg = "cyan" } -"ui.explorer.exe" = { fg = "foreground" } -"ui.explorer.focus" = { modifiers = ["reversed"] } -"ui.explorer.unfocus" = { bg = "secondary_highlight" } - -||||||| f0f295a6 -======= -"diagnostic".underline = { color = "orange", style = "curl" } -"diagnostic.error".underline = { color = "red", style = "curl" } - ->>>>>>> origin/master -[palette] -background = "#282a36" -background_dark = "#21222c" -primary_highlight = "#800049" -secondary_highlight = "#4d4f66" -foreground = "#f8f8f2" -comment = "#6272a4" -red = "#ff5555" -orange = "#ffb86c" -yellow = "#f1fa8c" -green = "#50fa7b" -purple = "#bd93f9" -cyan = "#8be9fd" -pink = "#ff79c6" diff --git a/runtime/themes/ingrid.toml.orig b/runtime/themes/ingrid.toml.orig deleted file mode 100644 index 3e9ab6ad..00000000 --- a/runtime/themes/ingrid.toml.orig +++ /dev/null @@ -1,84 +0,0 @@ -# Author : Ingrid Rebecca Abraham - -"attribute" = "#839A53" -"keyword" = { fg = "#D74E50", modifiers = ["bold"] } -"keyword.directive" = "#6F873E" -"namespace" = "#839A53" -"punctuation" = "#C97270" -"punctuation.delimiter" = "#C97270" -"operator" = { fg = "#D74E50", modifiers = ["bold"] } -"special" = "#D68482" -"variable.other.member" = "#89BEB7" -"variable" = "#A6B6CE" -"variable.parameter" = "#89BEB7" -"type" = { fg = "#A6B6CE", modifiers = ["bold"] } -"type.builtin" = "#839A53" -"constructor" = { fg = "#839A53", modifiers = ["bold"] } -"function" = { fg = "#89BEB7", modifiers = ["bold"] } -"function.macro" = { fg = "#D4A520", modifiers = ["bold"] } -"function.builtin" = "#89BEB7" -"comment" = "#A6B6CE" -"variable.builtin" = "#D4A520" -"constant" = "#D4A520" -"constant.builtin" = "#D4A520" -"string" = "#D74E50" -"constant.numeric" = "#D74E50" -"constant.character.escape" = { fg = "#D74E50", modifiers = ["bold"] } -"label" = "#D68482" - -"module" = "#839A53" - -# TODO -"markup.heading" = "blue" -"markup.list" = "red" -"markup.bold" = { fg = "yellow", modifiers = ["bold"] } -"markup.italic" = { fg = "magenta", modifiers = ["italic"] } -"markup.link.url" = { fg = "yellow", modifiers = ["underlined"] } -"markup.link.text" = "red" -"markup.quote" = "cyan" -"markup.raw" = "green" - -"diff.plus" = "#839A53" -"diff.delta" = "#D4A520" -"diff.minus" = "#D74E50" - -"ui.background" = { bg = "#FFFCFD" } -"ui.linenr" = { fg = "#bbbbbb" } -"ui.linenr.selected" = { fg = "#ED5466", modifiers = ["bold"] } -"ui.cursorline" = { bg = "#F3EAE9" } -"ui.statusline" = { fg = "#250E07", bg = "#F3EAE9" } -"ui.statusline.inactive" = { fg = "#7b91b3", bg = "#F3EAE9" } -"ui.popup" = { fg = "#7B91b3", bg = "#F3E8E9" } -"ui.window" = { bg = "#D8B8B3" } -"ui.help" = { bg = "#D8B8B3", fg = "#250E07" } - -"ui.text" = { fg = "#7B91B3" } -"ui.text.focus" = { fg = "#250E07", modifiers= ["bold"] } -"ui.virtual.whitespace" = "#A6B6CE" -"ui.virtual.ruler" = { bg = "#F3EAE9" } - -"ui.selection" = { bg = "#F3EAE9" } -"ui.cursor.primary" = { bg = "#ED5466", fg = "#FFFCFD", modifiers = ["bold"] } -"ui.cursor.match" = { bg = "#F3EAE9", fg = "#ED5466", modifiers = ["bold"] } -"ui.menu" = { fg = "#7B91B3", bg = "#F3EAE9" } -"ui.menu.selected" = { fg = "#D74E50", bg = "#F3EAE9" } - -"warning" = "#D4A520" -"error" = "#D74E50" -"info" = "#839A53" -"hint" = "#A6B6CE" -<<<<<<< HEAD - -"ui.explorer.file" = { fg = "#7B91B3" } -"ui.explorer.dir" = { fg = "#89BEB7" } -"ui.explorer.exe" = { fg = "#7B91B3" } -"ui.explorer.focus" = { modifiers = ["reversed"] } -"ui.explorer.unfocus" = { bg = "#F3EAE9" } -||||||| 7ac72a39 -======= - -"diagnostic.warning" = { underline = { color = "#D4A520", style = "curl" } } -"diagnostic.error" = { underline = { color = "#D74E50", style = "curl" } } -"diagnostic.info" = { underline = { color = "#839A53", style = "curl" } } -"diagnostic.hint" = { underline = { color = "#A6B6CE", style = "curl" } } ->>>>>>> master diff --git a/runtime/themes/serika-light.toml.orig b/runtime/themes/serika-light.toml.orig deleted file mode 100644 index 4c953687..00000000 --- a/runtime/themes/serika-light.toml.orig +++ /dev/null @@ -1,114 +0,0 @@ -# Serika (Light) -# Author: VuiMuich - -# Original Author: -# URL: https://github.com/arturoalviar/serika-syntax -# Author: arturoalviar -# License: MIT License - -"escape" = "orange" -"type" = "yellow" -"constant" = "purple" -"number" = "purple" -"string" = "fg" -"comment" = "grey2" -"variable" = "yellow" -"variable.builtin" = "blue" -"variable.parameter" = "yellow" -"variable.property" = "yellow" -"label" = "aqua" -"punctuation" = "grey0" -"punctuation.delimiter" = "grey2" -"punctuation.bracket" = "fg" -"keyword" = "red" -"operator" = "grey0" -"function" = "green" -"function.builtin" = "blue" -"function.macro" = "aqua" -"tag" = "yellow" -"namespace" = "fg" -"attribute" = "aqua" -"constructor" = "yellow" -"module" = "blue" -"special" = "orange" - -"ui.background" = { bg = "bg0" } -"ui.cursor" = { fg = "bg0", bg = "fg" } -"ui.cursor.match" = { fg = "grey1", bg = "grey2" } -"ui.cursor.insert" = { fg = "bg0", bg = "bg_yellow" } -"ui.cursor.select" = { fg = "bg0", bg = "bg_yellow" } -"ui.linenr" = "yellow" -"ui.linenr.selected" = { fg = "fg", modifiers = ["bold", "underlined"] } -"ui.cursorline" = { bg = "bg01" } -"ui.statusline" = { fg = "grey1", bg = "bg5" } -"ui.statusline.inactive" = { fg = "grey2", bg = "bg1" } -"ui.popup" = { fg = "bg0", bg = "bg5" } -"ui.window" = { fg = "bg0", bg = "bg5" } -"ui.help" = { fg = "bg0", bg = "bg5" } -"ui.text" = "fg" -"ui.text.focus" = "yellow" -"ui.menu" = { fg = "bg0", bg = "bg3" } -"ui.menu.selected" = { fg = "bg0", bg = "bg_yellow" } -"ui.selection" = { fg = "bg0", bg = "bg3" } -"ui.virtual.whitespace" = { fg = "bg2" } -"ui.virtual.ruler" = { bg = "bg01" } - -"hint" = "blue" -"info" = "aqua" -"warning" = "yellow" -"error" = "nasty-red" -"diagnostic" = { fg = "nasty-red", modifiers = ["underlined"] } - -"diff.plus" = { fg = "bg_green" } -"diff.delta" = { fg = "bg_blue" } -"diff.minus" = { fg = "nasty-red" } - -"markup.heading" = { fg = "purple", modifiers = ["bold"] } -"markup.list" = "cyan" -"markup.bold" = { fg = "orange", modifiers = ["bold"] } -"markup.italic" = { fg = "yellow", modifiers = ["italic"] } -"markup.link.url" = "cyan" -"markup.link.text" = "pink" -"markup.quote" = { fg = "yellow", modifiers = ["italic"] } -"markup.raw" = { fg = "fg" } - -<<<<<<< HEAD -"ui.explorer.file" = { fg = "fg" } -"ui.explorer.dir" = { fg = "blue" } -"ui.explorer.exe" = { fg = "fg" } -"ui.explorer.focus" = { modifiers = ["reversed"] } -"ui.explorer.unfocus" = { bg = "bg3" } - -||||||| f0f295a6 - -======= ->>>>>>> origin/master -[palette] - -bg0 = "#e1e1e3" -bg01 = "#eaeaec" -bg1 = "#494c50" -bg2 = "#55585e" -bg3 = "#61656b" -bg4 = "#6d7278" -bg5 = "#797e86" -bg_visual = "#646669" -bg_red = "#7e2a33" -bg_green = "#86b365" -bg_blue = "#6a89af" -bg_yellow = "#e2b714" - -fg = "#323437" -red = "#621d28" -nasty-red = "#da3333" -dark-red = "#791717" -orange = "#57320f" -yellow = "#9a7d0e" -green = "#3f4b34" -aqua = "#455054" -blue = "#3f5673" -purple = "#534059" -grey0 = "#aaaeb3" -grey1 = "#e1e1e3" -grey2 = "#646669" -pink = "#e06c75"