{"id":13620762,"url":"https://github.com/brotzeit/rustic","last_synced_at":"2026-01-26T21:50:57.986Z","repository":{"id":37276033,"uuid":"113447856","full_name":"brotzeit/rustic","owner":"brotzeit","description":"Rust development environment for Emacs","archived":false,"fork":false,"pushed_at":"2024-08-23T14:38:18.000Z","size":2490,"stargazers_count":730,"open_issues_count":92,"forks_count":101,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-03-14T02:09:45.978Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Emacs Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brotzeit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-12-07T12:24:30.000Z","updated_at":"2025-03-07T18:16:45.000Z","dependencies_parsed_at":"2024-05-05T06:26:24.269Z","dependency_job_id":"d09fb3f9-5163-454c-b710-c80432dc840c","html_url":"https://github.com/brotzeit/rustic","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/brotzeit/rustic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brotzeit%2Frustic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brotzeit%2Frustic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brotzeit%2Frustic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brotzeit%2Frustic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brotzeit","download_url":"https://codeload.github.com/brotzeit/rustic/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brotzeit%2Frustic/sbom","scorecard":{"id":254651,"data":{"date":"2025-08-11","repo":{"name":"github.com/brotzeit/rustic","commit":"1f4d6a315824487c88b5e1f6c0ad8a984def2c3d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.6,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":8,"reason":"Found 10/12 approved changesets -- score normalized to 8","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/brotzeit/rustic/test.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/brotzeit/rustic/test.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/brotzeit/rustic/test.yml/master?enable=pin","Warn: downloadThenRun not pinned by hash: .github/workflows/test.yml:37","Info:   0 out of   1 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned","Info:   0 out of   1 downloadThenRun dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE-APACHE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE-APACHE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T09:20:43.272Z","repository_id":37276033,"created_at":"2025-08-17T09:20:43.272Z","updated_at":"2025-08-17T09:20:43.272Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28789122,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T21:49:50.245Z","status":"ssl_error","status_checked_at":"2026-01-26T21:48:29.455Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T21:00:59.209Z","updated_at":"2026-01-26T21:50:57.956Z","avatar_url":"https://github.com/brotzeit.png","language":"Emacs Lisp","funding_links":[],"categories":["Development tools","开发工具 Development tools","Emacs Lisp"],"sub_categories":["IDEs","编译器 IDEs"],"readme":"# Rustic\n\n[![MELPA](https://melpa.org/packages/rustic-badge.svg)](https://melpa.org/#/rustic)\n[![](https://github.com/brotzeit/rustic/workflows/CI/badge.svg)](https://github.com/brotzeit/rustic/actions?query=workflow%3ACI)\n\n---\n### **UPDATE 2024-05-31**: This repository is not active anymore.\n\nA maintained fork of this repo has been created at https://github.com/emacs-rustic/rustic\n---\n\n\u003c!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc --\u003e\n**Table of Contents**\n\n- [Rustic](#rustic)\n    - [Intro](#intro)\n    - [Known issues](#known-issues)\n    - [Installation](#installation)\n        - [package](#package)\n        - [straight](#straight)\n    - [remote](#remote)\n    - [Compilation](#compilation)\n        - [Navigating errors](#navigating-errors)\n        - [default directory](#default-directory)\n        - [Faces](#faces)\n        - [rustc errors](#rustc-errors)\n    - [Rustfmt](#rustfmt)\n        - [Change default arguments](#change-default-arguments)\n        - [edition 2018](#edition-2018)\n        - [remote](#remote-1)\n    - [LSP](#lsp)\n        - [Server](#server)\n            - [Automatic server installation](#automatic-server-installation)\n        - [Client](#client)\n            - [eglot](#eglot)\n            - [lsp-mode](#lsp-mode)\n                - [`lsp-execute-code-action`](#lsp-execute-code-action)\n                    - [Applying code actions](#applying-code-actions)\n                    - [Auto import](#auto-import)\n                - [Macro expansion](#macro-expansion)\n        - [LSP + TRAMP](#lsp--tramp)\n        - [Detached file](#detached-file)\n    - [Cargo](#cargo)\n        - [Edit](#edit)\n        - [Test](#test)\n        - [Run](#run)\n        - [Outdated](#outdated)\n        - [Expand](#expand)\n        - [Spellcheck](#spellcheck)\n        - [More cargo commands](#more-cargo-commands)\n    - [Clippy](#clippy)\n        - [auto-fixing before compilation](#auto-fixing-before-compilation)\n        - [Commands](#commands)\n        - [Flycheck](#flycheck)\n        - [lsp-mode](#lsp-mode-1)\n    - [Org-babel](#org-babel)\n        - [Intro](#intro-1)\n        - [lsp-mode](#lsp-mode-2)\n        - [Commands](#commands-1)\n        - [Parameters](#parameters)\n            - [:crates](#crates)\n            - [:features](#features)\n            - [:paths](#paths)\n            - [:toolchain](#toolchain)\n            - [:main](#main)\n            - [:include](#include)\n            - [:use](#use)\n    - [Envrc](#envrc)\n    - [Spinner](#spinner)\n    - [rust docs in org-mode](#rust-docs-in-org-mode)\n        - [Prerequisites](#prerequisites)\n        - [Usage](#usage)\n        - [Notes](#notes)\n    - [Popup](#popup)\n    - [rust-mode](#rust-mode)\n    - [elisp tests](#elisp-tests)\n    - [Contributing](#contributing)\n\n\u003c!-- markdown-toc end --\u003e\n\n\n## Intro\n\nThis package is based on [rust-mode](https://github.com/rust-lang/rust-mode) and provides additional features:\n\n- cargo popup\n- multiline error parsing\n- translation of ANSI control sequences through\n  [xterm-color](https://github.com/atomontage/xterm-color)\n- async org babel\n- automatic LSP configuration with\n  [eglot](https://github.com/joaotavora/eglot) or\n  [lsp-mode](https://github.com/emacs-lsp/lsp-mode)\n- cask for testing\n- etc.\n\nrustic only shares the rust-mode code from rust-mode.el and rust-utils.el.\nThe other files provide functionality that is similar to some of the features\nof rustic, however can be considered light-weight compared to some rustic's\nfunctionality.\n\nThe shared functions and options exist as aliases in the rust-mode and\nrustic namespace for backwards compatibility reasons(rustic has been a fork).\n\n## Known issues\n\n- `rust-syntax-propertize` and `adaptive-wrap-prefix-mode` can lead to\n  severe lag when editing larger files (#107)\n\n## Installation\n\nFirst, you may need to install `rust-analyzer`. See [Automatic server installation](#automatic-server-installation).\n\nIf you can't run rust-analyzer or cargo can't be found, your\nenvironment variables probably don't work in emacs. Try\n[exec-path-from-shell](https://github.com/purcell/exec-path-from-shell/tree/81125c5adbc903943c016c2984906dc089372a41#usage)\nto fix this.\n\n### package\n\nThis section explains how to install rustic with the default package manager.\nIt's necessary to include elpa for a package dependency:\n\n```elisp\n(require 'package)\n(setq package-archives '((\"melpa\" . \"http://melpa.org/packages/\")\n                         (\"gnu\" . \"http://elpa.gnu.org/packages/\")))\n(package-initialize)\n(package-refresh-contents)\n(use-package rustic)\n```\n\nIf ‘spinner-1.7.3’ is unavailable” when trying to install rustic, you\nneed to update GPG keys used by the ELPA package manager. Try\ninstalling\n[gnu-elpa-keyring-update](https://elpa.gnu.org/packages/gnu-elpa-keyring-update.html).\n\n### straight\n\n[straight.el](https://github.com/raxod502/straight.el#install-packages)\nclones each of your packages directly from its source. There are good\nadditional [installation\ninstructions](https://github.crookster.org/switching-to-straight.el-from-emacs-26-builtin-package.el/)\nfor moving your package management from package.el to straight.\n\n## remote\n\nrustfmt and most of the common cargo commands should work remotely.\nWe are currently updating the code base. If you encounter any command\nthat doesn't work remotely, please open an issue.\n\n## Compilation\n\n![](https://raw.githubusercontent.com/brotzeit/rustic/master/img/compilation_buffer.png)\n\nIf you want to use a Makefile you can either use `(setq\nrustic-compile-command \"make\")` or run `C-u` + `rustic-compile`.\n\nCommands:\n\n- `rustic-compile`            compile project using `rustic-compile-command`\n- `rustic-recompile`          recompile using `compilation-arguments`\n- `rustic-compile-send-input` send string to process of current buffer\n\nCustomization:\n\n- `rustic-compile-display-method` choose function that displays the\n  compilation buffer (use the function `ignore`, if you don't want the\n  buffer to be displayed)\n- `rustic-compile-backtrace` change backtrace verbosity\n- `rustic-compile-rustflags` set RUSTFLAGS\n- `rustic-compile-command` default command for rust compilation\n- `rustic-compile-command-remote` default command for remote rust compilation\n\nSupported compile.el variables:\n\n- compilation-arguments\n- compilation-scroll-output (possible values are `t` for automatic scrolling and `first-error` to scroll to first error)\n\n### Navigating errors\n\nRustic defines a derived compilation-mode. Colors can be customized\nwith several defcustoms.  You can use `next-error` and\n`compilation-next-error` as for any other compilation buffer.\n\nHowever it's possible to also jump to line numbers that are displayed\nat the beginning of a line.  This feature is provided by a hook around\n`compile-goto-error`(`RET`).\n\n### default directory\n\n`rustic-compile-directory-method` allows you to set the directory that\nis used for compilation commands. The default is the current crate\nwhich is returned by `rustic-buffer-crate`(there's also\n`rustic-buffer-workspace`).\n\nIf you want to use the project root you can use `rustic-project-root`\ninstead.\n\nFTR #174 #179 #236\n\n### Faces\n\nThe colors that are displayed in compilation buffers come from cargo\nand are translated by xterm-color. You can change these colors by\nmodifying `rustic-ansi-faces`.\n\n`rustic-compilation-mode` doesn't use the default faces of\ncompile.el. If you want to change these colors you can use something\nsimilar to:\n\n```elisp\n(custom-set-faces\n  '(rustic-compilation-column ((t (:inherit compilation-column-number))))\n  '(rustic-compilation-line ((t (:foreground \"LimeGreen\")))))\n```\n\nAdditional faces:\n\n- `rustic-message`\n- `rustic-compilation-error`\n- `rustic-compilation-warning`\n- `rustic-compilation-info`\n\n### rustc errors\n\n![](https://raw.githubusercontent.com/brotzeit/rustic/master/img/rustc_errno.png)\n\n## Rustfmt\n\nEnsure rustfmt is installed by running `rustup component add rustfmt-preview`\nin your project's directory.\n\nYou can format your code with:\n\n- `rustic-format-buffer` format buffer with stdin\n- `rustic-format-file`   format file and revert buffer\n- `rustic-cargo-fmt`     run cargo-fmt on workspace\n- `rustic-format-region` format active region\n- `rustic-format-dwim`   run format on region,file or cargo fmt\n\nRustic uses the function `rustic-save-some-buffers` for saving buffers\nbefore compilation.\n\nTo save buffers automatically, you can change the value of\n`compilation-ask-about-save`, it has higher precedence than\n`buffer-save-without-query` when compiling.\n\n```elisp\n(defun rustic-mode-auto-save-hook ()\n  \"Enable auto-saving in rustic-mode buffers.\"\n  (when buffer-file-name\n    (setq-local compilation-ask-about-save nil)))\n(add-hook 'rustic-mode-hook 'rustic-mode-auto-save-hook)\n```\n\nCustomization:\n\n- `rustic-rustfmt-bin` path to rustfmt executable\n- `rustic-rustfmt-bin-remote` default path to remote rustfmt executable\n- `rustic-rustfmt-args` additional args like +nightly\n- `rustic-rustfmt-config-alist` alist of rustfmt configuration options\n- `rustic-format-display-method` default function used for displaying\n  rustfmt buffer (use the function `ignore`, if you don't want the\n  buffer to be displayed)\n- `rustic-format-on-save-method` function to use for on-save formatting\n- `rustic-format-trigger`\n  * `'on-save` format buffer before saving\n  * `'on-compile` run 'cargo fmt' before compilation\n  * `nil` don't format automatically\n- `rustic-use-rust-save-some-buffers` turn on to use automatic formatting\n  for `save-some-buffers`\n\nknown issues:\n\nin case you are using hideshow you might want to set `rustic-format-on-save-method` to `rustic-format-buffer`(#274)\n\n### Change default arguments\n\nIf you want to configure the following rustfmt call\n\n```shell\nrustfmt +nightly --config hard_tabs=true --config skip_children=false main.rs\n```\n\nyou can use\n\n```elisp\n(setq rustic-rustfmt-args \"+nightly\")\n(setq rustic-rustfmt-config-alist '((hard_tabs . t) (skip_children . nil)))\n```\n\n### edition 2018\n\nIf you are struggling with errors relating to the Rust edition in\n`Cargo.toml`, this may in fact be a problem with `rustfmt` and its\ndefault settings. To solve this, *even though the error message\nmentions `Cargo.toml`*, you have to put `edition = \"2018\"` in a\n`rustfmt.toml`. [See here for more\ninfo](https://github.com/rust-lang/rustfmt/issues/4454).\n\n### remote\n\nCurrently only `rustic-format-buffer` works remotely.\n\n`rustic-rustfmt-bin` needs to be an absolute path to work remotely.\n\n## LSP\n\nDisable `rustic-lsp-setup-p` to turn off automatic LSP configuration.\nIf you want to turn off LSP temporarily you can set\n`rustic-lsp-client` to nil. You have to restart emacs when you switch\nlsp clients.\n\nDon't forget that rustic doesn't contain the code for interacting with\nlsp servers. Therefore most issues are not related to rustic, but\nto the lsp client or server you are using.\n\n### Server\n\nrust-analyzer is the default and can be changed to rls if required (Note that rls\nis deprecated and is slated to be removed). lsp-mode related code was\nmoved to the lsp-mode repo.  `rustic-lsp-server` sets the value of\n`lsp-rust-server`.\n\nChange rust-analyzer path.\n\n``` emacs-lisp\n(setq rustic-analyzer-command '(\"~/.cargo/bin/rust-analyzer\"))\n```\n\nIf you are using rustup to [manage your rust-analyzer](https://rust-analyzer.github.io/manual.html#rustup), you would\nhave to configure like this to make it work with `use-package`:\n\n``` emacs-lisp\n(use-package rustic\n  :custom\n  (rustic-analyzer-command '(\"rustup\" \"run\" \"stable\" \"rust-analyzer\")))\n```\n\n#### Automatic server installation\n\nlsp-mode provides this feature, but eglot doesn't [#403](https://github.com/brotzeit/rustic/issues/403)\n\nInstall [rust-analyzer manually](https://rust-analyzer.github.io/manual.html#installation).\n\n### Client\n\nThe default package is `lsp-mode`. But you can also use `eglot`.\n\n``` emacs-lisp\n(setq rustic-lsp-client 'eglot)\n```\n\nLSP commands:\n\n- `xref-find-definitions` find definitions\n- `xref-find-references` with helm and rust-analyzer\n- `rustic-cargo-add-missing-dependencies` convenient command that adds missing dependencies to a crate's Cargo.toml\n\n![](https://raw.githubusercontent.com/brotzeit/rustic/master/img/xref_references.png)\n\n#### eglot\n\nTurn off flymake.\n\n``` emacs-lisp\n(add-hook 'eglot--managed-mode-hook (lambda () (flymake-mode -1)))\n```\n\n#### lsp-mode\n\n- `lsp-describe-thing-at-point` display documentation\n- `lsp-find-definition` makes use of xref\n\nYou can find more information in the [lsp-mode documentation for Rust](https://emacs-lsp.github.io/lsp-mode/page/lsp-rust-analyzer/).\n\n##### `lsp-execute-code-action`\n\nThis command can be extremely convenient when applying code actions or\nusing auto-imports.\n\nRun `lsp-execute-code-action` when lsp-ui displays code actions at the\ntop of the sideline.\n\n###### Applying code actions\n\n![](https://raw.githubusercontent.com/brotzeit/rustic/master/img/code_actions.png)\n\n###### Auto import\n\n![](https://raw.githubusercontent.com/brotzeit/rustic/master/img/auto_import.png)\n\n##### Macro expansion\n\n`lsp-rust-analyzer-expand-macro` expand macro call at point\nrecursively.\n\nThe results are formatted and highlighted by default, but you can use\nyour own function by customizing\n`lsp-rust-analyzer-macro-expansion-method`.\n\n![](https://raw.githubusercontent.com/brotzeit/rustic/master/img/macro_expansion.png)\n\n### LSP + TRAMP\n\n`rust-analyzer` does work over TRAMP, but you have to register the client\nmanually:\n\n``` elisp\n(with-eval-after-load \"lsp-rust\"\n (lsp-register-client\n  (make-lsp-client\n   :new-connection (lsp-stdio-connection\n                    (lambda ()\n                      `(,(or (executable-find\n                              (cl-first lsp-rust-analyzer-server-command))\n                             (lsp-package-path 'rust-analyzer)\n                             \"rust-analyzer\")\n                        ,@(cl-rest lsp-rust-analyzer-server-args))))\n   :remote? t\n   :major-modes '(rust-mode rustic-mode)\n   :initialization-options 'lsp-rust-analyzer--make-init-options\n   :notification-handlers (ht\u003c-alist lsp-rust-notification-handlers)\n   :action-handlers (ht (\"rust-analyzer.runSingle\" #'lsp-rust--analyzer-run-single))\n   :library-folders-fn (lambda (_workspace) lsp-rust-library-directories)\n   :after-open-fn (lambda ()\n                    (when lsp-rust-analyzer-server-display-inlay-hints\n                      (lsp-rust-analyzer-inlay-hints-mode)))\n   :ignore-messages nil\n   :server-id 'rust-analyzer-remote)))\n```\n\n*(based on https://github.com/emacs-lsp/lsp-mode/blob/68fddd5d9c5506b2adf6a3f67bbe568f44563dd4/clients/lsp-rust.el#L644)*\n\nIf you have Emacs 28, due to some [compatibility issues](https://github.com/emacs-lsp/lsp-mode/issues/2514#issuecomment-759452037),\nyou might have to additionally use:\n\n``` elisp\n(defun start-file-process-shell-command@around (start-file-process-shell-command name buffer \u0026rest args)\n  \"Start a program in a subprocess.  Return the process object for it. Similar to `start-process-shell-command', but calls `start-file-process'.\"\n  ;; On remote hosts, the local `shell-file-name' might be useless.\n  (let ((command (mapconcat 'identity args \" \")))\n    (funcall start-file-process-shell-command name buffer command)))\n\n(advice-add 'start-file-process-shell-command :around #'start-file-process-shell-command@around)\n```\n\n*(thanks to https://github.com/emacs-lsp/lsp-mode/issues/2514#issuecomment-759452037)*\n\nYou'll have to have `rust-analyzer` already installed on the target machine.\n\n### Detached file\n\nThis is an early experimental feature, and is disabled by default.\n\nSource files not belonging to any crate, or _detached_ source files,\nare supported by rust-analyzer, and this feature can be enabled via\n`rustic-enable-detached-file-support`. (Currently, only eglot is\nsupported.)\n\n**Caveat**: Due to some current limitations, you should avoid opening\na detached file in a large directory with this feature enabled.\n\n## Cargo\n\nSince the cargo commands also use the derived compilation mode, you can use\nthe commands that are mentioned in the \"compilation\" section.\n\nCustomization:\n\n- `rustic-cargo-bin` Path to cargo executable\n- `rustic-cargo-bin-remote` Path to remote cargo executable\n- `rustic-cargo-build-arguments` default arguments for cargo build\n- `rustic-cargo-check-arguments` default arguments for cargo check\n- `rustic-cargo-auto-add-missing-dependencies` automatically add missing dependencies\nto Cargo.toml by checking new diagnostics for 'unresolved import' errors\n- `rustic-cargo-use-last-stored-arguments` always use stored arguments that were provided with `C-u`(instead of requiring to run rustic \"rerun\" commands)\n\n### Edit\n\n[cargo-edit](https://github.com/killercup/cargo-edit) provides commands to edit\nyour dependencies quickly.\n\nThe rustic commands can be called with prefix `C-u` if you want to\nmodify the parameters of a command.\n\n- `rustic-cargo-add`      Add crate to Cargo.toml using 'cargo add'\n- `rustic-cargo-rm`       Remove crate from Cargo.toml using 'cargo rm'\n- `rustic-cargo-upgrade`  Upgrade dependencies as specified in the local manifest file using 'cargo upgrade'\n- `rustic-cargo-add-missing-dependencies` Add the missing dependencies for the current buffer to `Cargo.toml`\n\n### Test\n\nIf you want to disable warnings when running cargo-test commands, you can set\n`(setq rustic-cargo-test-disable-warnings t)`.\n\nCommands:\n\n`rustic-cargo-nextest-exec-command` command for running [nextest](https://github.com/nextest-rs/nextest)\n`rustic-cargo-test` run 'cargo test', when called with `C-u` store\narguments in `rustic-test-arguments`\n\n`rustic-cargo-test-rerun` rerun 'cargo test' with arguments stored in\n`rustic-test-arguments`\n\n`rustic-cargo-current-test` run test at point, whether it's a function or a module\n\n![](https://raw.githubusercontent.com/brotzeit/rustic/master/img/cargo_current_test.png)\n\n### Run\n\nBased on the usecase, we provide three variants of it:\n\n- `rustic-cargo-run`\n\nThis is meant for non interactive programs. It's creates a new mode\nwhich is built on top of `rustic-compilation-mode`. You can press `g`\nin this mode's buffer to make it re-run.\n\n- `rustic-cargo-comint-run`\n\nThis is meant for both interactive and non interactive programs. For\nnon interactive programs, you would need to pass data to it via stdin.\nIt's creates a new mode which is built on top of `comint-mode`. You\ncan press `C-c C-g` in this mode's buffer to make it re-run.  You can\npass input to the program directly in it's output buffer and press `RET`.\n\n- `rustic-cargo-plain-run`\n\nThis is similar to the above `rustic-cargo-comint-run`. Input can be\nsent to the program in one of two ways:\n\n- `rustic-compile-send-input`, which reads the input from the\n  minibuffer.\n- `rustic-cargo-run-use-comint`: when this variable is set to t, the\n  input can be typed directly into the output buffer of 'cargo run'\n  and sent off with `RET`, just like in `comint-mode`.  You need\n  [polymode](https://polymode.github.io) installed for this to work.\n\n### Outdated\n\nUse `rustic-cargo-outdated` to get a list of dependencies that are out\nof date. The results are displayed in `tabulated-list-mode` and you\ncan use most commands you know from the emacs package menu. This\noption requires the rust package `cargo-outdated` to be installed\nbefore being used.\n\n- `u` mark single crate for upgrade and prompt user for version.\n- `U` mark all upgradable crates.\n- `l` mark single crate for upgrading to latest version.\n- `L` mark all crates to latest version.\n- `m` remove mark\n- `x` perform marked package menu actions\n- `r` refresh crate list\n- `q` quit window\n\n![](https://raw.githubusercontent.com/brotzeit/rustic/master/img/outdated.png)\n\n### Expand\n\n[cargo-expand](https://github.com/dtolnay/cargo-expand) provides the ability to expand macros. It also\nprovides the ability to target a specific modules or a named item\nwithin a module (eg: `module::Type`).\n\n- `rustic-cargo-expand`: runs `cargo expand`. You can also use\n  universal argument to target a specific named item to expand.\n\n### Spellcheck\n\n[cargo spellcheck](https://github.com/drahnr/cargo-spellcheck) checks the documentation for spelling and\ngrammar mistakes.\n\n- `rustic-cargo-spellcheck`: runs `cargo spellcheck` and will open a\n  buffer where you can go through the various errors pointed out by\n  it.\n\n### More cargo commands\n\n- `rustic-cargo-init` run 'cargo init' to initialize a directory\n- `rustic-cargo-new` use 'cargo new' to create a new package\n- `rustic-cargo-bench` run 'cargo bench' for the current project\n- `rustic-cargo-build-doc` build the documentation for the current project\n- `rustic-cargo-doc` open the documentation for the current project in a browser\n- `rustic-cargo-lints` called with `rustic-lints-arguments`\n- `rustic-cargo-install` run 'cargo install' on the current package.\n- `rustic-cargo-update` run `cargo update` on the current package.\n\n## Clippy\n\nCurrently cargo does not display the correct installation command for\nsome toolchains when clippy isn't installed.  If you have problems try\nit with `rustup component add --toolchain nightly clippy`.\n\nYou can change the parameters `rustic-default-clippy-arguments` that\ndefault to \"--benches --tests --all-features\".\n\n### auto-fixing before compilation\n\nIt's possible to run 'clippy --fix' automatically when starting a compile\nprocess by setting `rustic-cargo-clippy-trigger-fix` to `'on-compile`.\nYou can also use `'on-save`, but this doesn't work in combination with\nautomatic formatting.\n\nThis feature can be used in combination with auto-formatting.\n\nWorks for:\n\n- `rustic-cargo-build`\n- `rustic-compile`\n- `rustic-recompile`\n\n### Commands\n\n- `rustic-cargo-clippy`     to view the results in a derived compilation mode\n- `rustic-cargo-clippy-fix` run 'clippy fix' using `rustic-cargo-clippy-fix-args`\n                            the default value is \"--allow-dirty\"\n\n### Flycheck\n\nIn case you want to use clippy with flycheck but without LSP, you can activate\nthis checker and use the command `flycheck-list-errors`\n\n```elisp\n(push 'rustic-clippy flycheck-checkers)\n```\n\nTurn off flycheck.\n\n```elisp\n(remove-hook 'rustic-mode-hook 'flycheck-mode)\n```\n\nThe checker automatically detects the active toolchain and applies the\ncorrect parameters. You can set a default value for both stable and\nnightly toolchains. These are the default values.\n\n- `rustic-flycheck-clippy-params-stable` \"--message-format=json\"\n- `rustic-flycheck-clippy-params-nightly` \"--message-format=json -Zunstable-options\"\n\n### lsp-mode\n\nIf you are using `lsp-mode` with rust-analyzer, you can set\n`lsp-rust-analyzer-cargo-watch-command` to clippy instead of\nactivating the checker `rustic-clippy`.\n\n## Org-babel\n\n### Intro\n\nBlocks run asynchronously and a running babel process is indicated by\na spinner in the mode-line. It's possible to use crates in babel\nblocks. Execute babel block with `org-babel-execute-src-block`.\n\nSupported org babel parameters:\n\nWrite to file `:results file :file ~/babel-output`\n\nCustomization:\n\n- `rustic-babel-format-src-block` format block after successful build\n- `rustic-babel-display-compilation-buffer` display compilation buffer\n  of babel process\n- `rustic-babel-auto-wrap-main` wrap body into main function\n- `rustic-babel-default-toolchain` active toolchain for babel blocks\n\n### lsp-mode\n\nYou can use lsp in babel blocks with `lsp-org`.\n\n### Commands\n\n- `rustic-babel-format-block` format block at point\n- `rustic-babel-header-insert-crates` include missing dependencies in `:crates` header arg\n- `rustic-babel-visit-project` find generated project of block at point\n- `rustic-babel-clippy` run clippy on block(currently doesn't honor babel params, you can open a feature request if you miss it)\n\n### Parameters\n\n#### :crates\n\nThis block shows how to use crates with the latest version for both\nserde and regex.\n\nThe \"*\" will be added automatically for serde.\n\n```\n#+BEGIN_SRC rust :crates '(serde (regex . *))\n  extern crate regex;\n  extern crate serde;\n  use regex::Regex;\n\n  fn main() {\n      let re = Regex::new(r\"^\\d{4}-\\d{2}-\\d{2}$\").unwrap();\n      assert!(re.is_match(\"2014-01-01\"));\n  }\n#+END_SRC\n```\n\n#### :features\n\nIf specific crate features are required then these can be specified\nwith the `:features` argument. Note that if it is just a single feature\nthen a string, instead of a list, will also be accepted:\n\n```\n#+BEGIN_SRC rust :crates '((tokio . 1.0)) :features '((tokio . (\"rt-multi-thread\" \"time\")))\n  extern crate tokio;\n\n  fn main() {\n      tokio::runtime::Runtime::new()\n          .unwrap()\n          .block_on(async {\n              tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;\n          });\n  }\n#+END_SRC\n```\n\n#### :paths\n\nSimilarly, to depend on local Rust crates, you can set the `:paths`\nargument:\n\n```\n#+BEGIN_SRC rust :crates '((foo . 1.0)) :paths '((foo . \"/home/you/code/foo\"))\n  use foo::Foo;\n\n  fn main() {\n    // Your code.\n  }\n#+END_SRC\n```\n\n#### :toolchain\n\nYou can specify the `:toolchain` by quoted `'stable`/`'nightly`/`'beta`,\nor specify a [toolchain version](https://rust-lang.github.io/rustup/concepts/toolchains.html) like `\"1.63.0\"`, `\"nightly-2022-08-08\"`.\n\n```\n#+begin_src rust :toolchain 'nightly\nfn main() {\n    let foo: String = vec![\"a\", \"b\", \"c\"].into_iter().intersperse(\",\").collect();\n\n    println!(\"{}\", foo);\n}\n#+end_src\n\n#+RESULTS:\n: a,b,c\n```\n\n#### :main\n\nAuto wrap whole block body in a `fn main` function call if none\nexists.\n\nSince this is very handy in most code snippets, so the default value\nis `yes`.  `no` if you don't want this feature(for example, you don't\nwant regex search slow things down).\n\nYou can also set a default value by:\n``` elisp\n;; By setq this default to `nil`, you'll have to explict set params to \":main yes\" in each block\n(setq rustic-babel-auto-wrap-main nil)\n```\n\n```\n#+begin_src rust :main yes\nlet x = vec![1, 2, 3].iter().map(|\u0026x| x + 1).collect::\u003cVec\u003c_\u003e\u003e();\nprintln!(\"{:?}\", x);\n#+end_src\n\n#+results:\n: [2, 3, 4]\n```\n\n#### :include\n\nThis parameter allows you to run code that is located in different\nbabel blocks by using named blocks with the `:include` keyword. This\nfeature only concats the blocks so you don't need to import the code\nyou want to use.\n\nYou can still use `:main` to wrap the code of the main block.\n\n```\n#+name: b1\n#+begin_src rust\npub fn b1_func() -\u003e String {\n    String::from(\"b1 function called\")\n}\n#+end_src\n\n#+name: b2\n#+begin_src rust\npub fn b2_func() -\u003e String {\n    String::from(\"b2 function called\")\n}\n#+end_src\n\n#+begin_src rust :include '(b1 b2)\n  fn main() {\n      println!(\"{:?}\", b1_func());\n      println!(\"{:?}\", b2_func());\n  }\n#+end_src\n\n#+RESULTS:\n: \"b1 function called\"\n: \"b2 function called\"\n```\n\n#### :use\n\nWhen using this keyword blocks are treated as modules. The files are\ngenerated automatically.\n\n```\n#+name: mymodule\n#+begin_src rust\npub fn myfunc() -\u003e String {\n    String::from(\"mymodule function called\")\n}\n#+end_src\n\n#+begin_src rust :use '(mymodule)\nuse mymodule::myfunc;\n\nfn main() {\n    println!(\"{:?}\", myfunc());\n}\n#+end_src\n\n#+RESULTS:\n: \"mymodule function called\"\n```\n\n\n## envrc\n\nTo load your Rust toolchain via [envrc](https://github.com/purcell/envrc), ensure that\nthe [inheritenv](https://github.com/purcell/inheritenv) package is available before\nloading rustic, so that auxiliary rustic buffers acquire the correct environment to find\nthe toolchain.\n\n## Spinner\n\nIn case you want to use a different spinner type you can modify\n`rustic-spinner-type` or turn it off completely with\n`rustic-display-spinner`.([Available spinner\ntypes](https://github.com/Malabarba/spinner.el/blob/master/spinner.el#L104)).\n\n## rust docs in org-mode\n\nIt is possible to read rust documentation inside Emacs! This currently\nrequires LSP-mode and cargo. Unfortunately, this probably won't work on Windows. ![Rustic-doc\nexample](img/rustic-doc.png)\n\n### Prerequisites\n\nRequired:\n\n- [pandoc](https://pandoc.org/installing.html) preferably at least version 2.11, as it will give somewhat nicer generated documentation. Versions older than 2.9 may not work - if you're on a debian based distro installing through your regular repo might not work out.\n- [cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html)\n- [cargo-makedocs](https://github.com/Bunogi/cargo-makedocs)\n- [fd-find](https://github.com/sharkdp/fd) Old versions, especially before 2.x, may not work. Install through Cargo if you're having issues.\n\nOptional:\n\n- [helm-ag](https://github.com/emacsorphanage/helm-ag)\n- [ripgrep](https://github.com/BurntSushi/ripgrep)\n\n`ripgrep` and `helm-ag` are optional but highly recommended.\n\nIf only ripgrep is installed, it will be used with the emacs `grep`\ncommand.  In case neither is available, the emacs `grep` command will\nuse `grep`, like in the good old days.\n\nWhen a required cargo package is missing you will be asked if you want\nto install them when running rustic-doc-setup.\n\n### Usage\n\n- Enable `rustic-doc-mode`.\n- Run `rustic-doc-setup` to download files that rustic-doc needs to\n  convert rust documentation and also convert `std`.\n- You can now convert package-specific documentation with\n  `rustic-doc-convert-current-package`\n- Search the org files with `rustic-doc-search` (bound to `C-#` by\n  default) if you are in `Rust mode`, `Rustic mode` or `Org mode`. If\n  you hover over a symbol when you invoke the command,\n  `rustic-doc-search` will insert a default value.\n- Add `universal argument` to only search for level 1 headers like\n  struct or enum names.\n\nYou can change the defaults by modifying\n\n- `rustic-doc-rg-search-command`\n- `rustic-doc-search-function`\n\n### Notes\n\n- You should re-run `rustic-doc-setup` once in a while, to update the\n  pandoc filter.\n- If rustic-doc does not find the documentation for something, the\n  first thing to do is check the project's `target/doc` folder for the\n  corresponding `.html-file`. If there is no file there, there is\n  nothing for rustic-doc to convert. If there is a file there, please\n  create an issue!\n\n## Popup\n\nYou can execute commands with `rustic-popup`(call it with optional\nargument `C-u` to choose a directory). The list of commands can be\ncustomized with `rustic-popup-commands`.  The command\n`rustic-popup-default-action` (`RET` or `TAB`) allows you to change:\n\n- `RUST_BACKTRACE` environment variable\n- `compilation-arguments` for `recompile`\n- arguments for `cargo test`\n\nIf you want to close the popup after you ran a command you can set\n`rustic-kill-buffer-and-window` to `t`.\n\n![](https://raw.githubusercontent.com/brotzeit/rustic/master/img/popup.png)\n\nView help buffer containing a command's flags with `h`:\n\n![](https://raw.githubusercontent.com/brotzeit/rustic/master/img/popup_help.png)\n\n## rust-mode\n\nrustic-mode derives from rust-mode, however we replace default key\nbindings and some hooks.\n\nThere are also some additional commands:\n\n- `rust-dbg-wrap-or-unwrap` Either remove or add the dbg! macro\n- `rust-toggle-mutability` Toggles the mutability of the variable defined on the current line\n- `rust-promote-module-into-dir` Promote the module file visited by the current buffer into its own directory\n\n## elisp tests\n\nTo run the tests, you will need [Cask](https://github.com/cask/cask).\n\n``` bash\ncask exec ert-runner\n```\n\nalternatively you can use `make test`\n\n## Contributing\n\nPRs, feature requests and bug reports are very welcome. If you want to\nadd a new feature please open an issue in advance so we can discuss\nthe details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrotzeit%2Frustic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrotzeit%2Frustic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrotzeit%2Frustic/lists"}