{"id":13861425,"url":"https://github.com/p3r7/friendly-shell","last_synced_at":"2025-08-16T14:32:01.786Z","repository":{"id":56764291,"uuid":"236243031","full_name":"p3r7/friendly-shell","owner":"p3r7","description":":shell: More convenient Emacs shell APIs ","archived":false,"fork":false,"pushed_at":"2023-09-16T14:26:56.000Z","size":56,"stargazers_count":30,"open_issues_count":1,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-08-16T03:51:08.014Z","etag":null,"topics":["emacs","shell","terminal"],"latest_commit_sha":null,"homepage":"","language":"Emacs Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/p3r7.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2020-01-25T23:16:53.000Z","updated_at":"2024-02-25T04:50:39.000Z","dependencies_parsed_at":"2024-04-08T16:58:35.089Z","dependency_job_id":"42e351ef-a8a2-46af-bc7d-3bffa682e3cb","html_url":"https://github.com/p3r7/friendly-shell","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/p3r7/friendly-shell","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p3r7%2Ffriendly-shell","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p3r7%2Ffriendly-shell/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p3r7%2Ffriendly-shell/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p3r7%2Ffriendly-shell/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/p3r7","download_url":"https://codeload.github.com/p3r7/friendly-shell/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p3r7%2Ffriendly-shell/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270723221,"owners_count":24634341,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-16T02:00:11.002Z","response_time":91,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["emacs","shell","terminal"],"created_at":"2024-08-05T06:01:22.012Z","updated_at":"2025-08-16T14:32:01.535Z","avatar_url":"https://github.com/p3r7.png","language":"Emacs Lisp","funding_links":[],"categories":["Emacs Lisp"],"sub_categories":[],"readme":"# friendly-shell\n\nWrappers functions around standard Emacs shell API functions, with saner defaults and additional keyword arguments.\n\nThey are split into 3 packages:\n\n - `friendly-shell-command`: wraps shell command API from simple.el ([blog post](https://www.eigenbahn.com/2020/01/19/painless-emacs-shell-commands))\n\n   [![MELPA](https://melpa.org/packages/friendly-shell-command-badge.svg)](https://melpa.org/#/friendly-shell-command)\n   [![MELPA Stable](https://stable.melpa.org/packages/friendly-shell-command-badge.svg)](https://stable.melpa.org/#/friendly-shell-command)\n\n - `friendly-shell`: wraps interactive shell API from shell.el ([blog post](https://www.eigenbahn.com/2020/01/21/painless-emacs-interactive-shells))\n\n   [![MELPA](https://melpa.org/packages/friendly-shell-badge.svg)](https://melpa.org/#/friendly-shell)\n   [![MELPA Stable](https://stable.melpa.org/packages/friendly-shell-badge.svg)](https://stable.melpa.org/#/friendly-shell)\n\n - `friendly-remote-shell`: command for human-friendly spawning of remote shells\n\n   [![MELPA](https://melpa.org/packages/friendly-remote-shell-badge.svg)](https://melpa.org/#/friendly-remote-shell)\n   [![MELPA Stable](https://stable.melpa.org/packages/friendly-remote-shell-badge.svg)](https://stable.melpa.org/#/friendly-remote-shell)\n\nExamples can be found in [examples.md](examples.md).\n\nThey rely heavily on package [with-shell-interpreter](https://github.com/p3r7/with-shell-interpreter).\n\n`friendly-remote-shell` relies additionally on helper package [friendly-tramp-path](https://github.com/p3r7/friendly-tramp-path).\n\nNB: These packages used to be called `prf-shell-command`, `prf-shell` and `prf-remote-shell`. You can still grab the legacy code with version [0.1.0](https://github.com/p3r7/friendly-shell/releases/tag/0.1.0).\n\n\n## Installation\n\nAll the packages are available on [Melpa](https://melpa.org/).\n\n```el\n(use-package friendly-shell-command)\n\n(use-package friendly-shell)\n\n(use-package friendly-remote-shell)\n```\n\n\n## General usage\n\nEach of functions provided by the package have the same behavior as their wrapped counterparts but come with additional keyword arguments.\n\nHere are the additional keywords that are shared by all the wrapper functions:\n\n| keyword argument    | implicit var being let-bound                   | description                                                                       |\n|---------------------|------------------------------------------------|-----------------------------------------------------------------------------------|\n| _:path_             | `default-directory`                            | The path from which to launch command / shell.                                    |\n| _:interpreter_      | `explicit-shell-file-name` / `shell-file-name` | Name or absolute path of shell interpreter executable.                            |\n| _:interpreter-args_ | `explicit-INTEPRETER-args`                     | Login args to call interpreter with for login.                                    |\n| _:command-switch_   | `shell-command-switch`                         | Command switch arg for asking interpreter to run a shell command.                 |\n| _:w32-arg-quote_    | `w32-quote-process-args`                       | Character to use for quoting shell arguments (only on the Windows build of Emacs) |\n\nIf _:path_ is remote, the command will be executed with the remote host interpeter.\n\nSee README of [with-shell-interpreter](https://github.com/p3r7/with-shell-interpreter) for more details.\n\nConcrete examples can be found in [examples.md](examples.md).\n\n\n## Functions index\n\n### Shell Commands\n\nHelpers functions to create commands launching (non-interactive) shell commands.\n\n* friendly-shell-command | [friendly-shell-command-to-string](#friendly-shell-command-to-string) `(cmd \u0026 :path :interpreter :command-switch)`\n* friendly-shell-command | [friendly-shell-command](#friendly-shell-command) `(cmd \u0026 :output-buffer :error-buffer :path :interpreter :interpreter-args :command-switch :callback :kill-buffer)`\n* friendly-shell-command | [friendly-shell-command-async](#friendly-shell-command-async) `(cmd \u0026 :output-buffer :error-buffer :path :interpreter :interpreter-args :command-switch :callback :kill-buffer :sentinel)`\n\n\n### Interactive Shells\n\nCommand for spawning interactive shells or helper function to create new interactive shell-spawning commands.\n\n* friendly-shell | [friendly-shell](#friendly-shell) `(\u0026 :path :interpreter :interpreter-args :command-switch :w32-arg-quote)`\n* friendly-remote-shell | [friendly-remote-shell](#friendly-remote-shell) `(\u0026 :path :interpreter :interpreter-args :command-switch :w32-arg-quote)`\n\n\n## Shell Commands\n\nEmacs provides some standard function for launching shell commands (from `simple.el`):\n\n| function                                                       | execution    | return value                      | spawned buffers   |\n| --                                                             | :--:         | --                                | --                |\n| _shell-command-to-string_ `(command)`                          | synchronous  | stdout                            |                   |\n| _shell-command_ `(command \u0026 output-buffer error-buffer)`       | synchronous  | return code                       | stdout and stderr |\n| _async-shell-command_ `(command \u0026 output-buffer error-buffer)` | asynchronous | _window_ containing output-buffer | stdout and stderr |\n\nPackage `friendly-shell-command` provide a wrapper around each of those.\n\nThey have the same behavior (sync/async, return value, spawned buffers) as their wrapped counterparts.\n\n\n#### friendly-shell-command-to-string\n\n`(cmd \u0026 :path :interpreter :command-switch)`\n\nCalls CMD with `shell-command-to-string` with _:interpreter_ at given _:path_.\n\n\n#### friendly-shell-command\n\n`(cmd \u0026 :output-buffer :error-buffer :path :interpreter :interpreter-args :command-switch :callback :kill-buffer)`\n\nCalls CMD synchronously with `shell-command` with _:interpreter_ at given _:path_.\n\nIn addition to the [common keywords](#General-usage), the following additional keyword can be used:\n\n| keyword          | description                                          | default value             |\n|------------------|------------------------------------------------------|---------------------------|\n| _:output-buffer_ | Buffer to output to.                                 | `*Shell Command Output*`  |\n| _:error-buffer_  | Buffer to output stderr to.                          | value of `:output-buffer` |\n| _:kill-buffer_   | If non-nil, will output buffer after execution       | `nil`                     |\n| _:callback_      | Function to run at the end of the command execution. | n/a                       |\n\nPlease note that `:callback` function should not take any argument (0-arity).\n\n\n#### friendly-shell-command-async\n\n`(cmd \u0026 :output-buffer :error-buffer :path :interpreter :interpreter-args :command-switch :callback :kill-buffer :sentinel)`\n\nCalls CMD asynchronously with `async-shell-command` with _:interpreter_ at given _:path_.\n\nIn addition to the [common keywords](#General-usage), the following additional keyword can be used:\n\n| keyword          | description                                          | default value             |\n|------------------|------------------------------------------------------|---------------------------|\n| _:output-buffer_ | Buffer to output to.                                 | `*Shell Command Output*`  |\n| _:error-buffer_  | Buffer to output stderr to.                          | value of `:output-buffer` |\n| _:kill-buffer_   | If non-nil, will output buffer after execution       | `nil`                     |\n| _:callback_      | Function to run at the end of the command execution. | n/a                       |\n| _:sentinel_      | Process sentinel to bind to the command process.     | n/a                       |\n\nPlease note that _:callback_ function should not take any argument (0-arity).\n\nFor the _:sentinel_ argument, you can read more about process sentinels in [the Emacs manual](https://www.gnu.org/software/emacs/manual/html_node/elisp/Sentinels.html).\n\n\n## Interactive Shells\n\n#### friendly-shell\n\n`(\u0026 :path :interpreter :interpreter-args :command-switch :w32-arg-quote)`\n\nSpawn a shell with `shell` with _:interpreter_ at given _:path_.\n\nWhen used as a command (i.e. called interactively), spawns a shell at current location (`default-directory`) with the default interpreter (`shell-file-name` or `with-shell-interpreter-default-remote` if on a remote server).\n\nContrarily to default `shell` behavior, the value of interpreter and its args are kept as buffer-local vars (`explicit-shell-file-name`, `explicit-\u003cinterpreter\u003e-args` ,`shell-command-switch`...).\n\nThis allows reusing the same interpreter config when launching shell commands from the spawned buffer.\n\n\n#### friendly-remote-shell\n\n`(\u0026 :path :interpreter :interpreter-args :command-switch :w32-arg-quote)`\n\nSame as `friendly-shell` but accept a more permissive remote path format (thanks to [p3r7/friendly-tramp-path](https://github.com/p3r7/friendly-tramp-path)).\n\nIf called as a command, will prompt user for _:path_, assuming it's a remote host.\n\nFor example:\n\n    M-x friendly-shell\n    Host: pi@raspberry\n\n\n## Complementary packages\n\nI highly encourage to use package [shx](https://github.com/riscy/shx-for-emacs) which provides various enhancement for interactive shell buffers.\n\nOne of the major improvement is the ability to resurrect dead shell buffers.\n\n\n## Similar projects\n\n#### [Howard Abrams' dot emacs](https://github.com/howardabrams/dot-files)\n\nHoward has a lot of goodies related to remote interactive shells and eshell.\n\nNotably:\n\n - command [eshell-here ](https://github.com/howardabrams/dot-files/blob/master/emacs-eshell.org#shell-here) that behaves like `friendly-shell` called interactively, except spawning eshell instead of shell.\n - command [eshell-there](https://github.com/howardabrams/dot-files/blob/master/emacs-eshell.org#shell-there) that is very similar to `friendly-remote-shell`, except spawning eshell instead of shell\n - [various commands](https://github.com/howardabrams/dot-files/blob/master/emacs-eshell.org#shell-favorites) for spawning remote shells given host aliases. He also defines a `remote-shell-command` that behaves like `friendly-shell-command`.\n\n\n#### [killdash9/better-shell](https://github.com/killdash9/better-shell)\n\nThis package provides command `better-shell-for-current-dir` which is very similar to `friendly-shell` called interactively. One key difference is that it implements a mechanism for reusing existing shell buffers if appropriate.\n\nIt also provides command `better-shell-remote-open` which behaves like `friendly-remote-shell` except it provides autocompletion from `~/.ssh/known_hosts`.\n\n\n#### [randymorris/tramp-term](https://github.com/randymorris/tramp-term.el)\n\nBindings between term.el and TRAMP to ease the creation of remote term buffers.\n\n\n## Legibility\n\nThis code uses form feeds (`^L` character) as separators.\n\nEither package [form-feed](https://github.com/wasamasa/form-feed) or [page-break-lines](https://github.com/purcell/page-break-lines) makes them appear as intended.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp3r7%2Ffriendly-shell","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fp3r7%2Ffriendly-shell","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp3r7%2Ffriendly-shell/lists"}