diff --git a/README.md b/README.md index 4c95acf..136dedf 100644 --- a/README.md +++ b/README.md @@ -19,68 +19,46 @@ Context-based replacement/enhancement for zsh and bash shell history **Search your history by commands or arguments and get relevant results based on current directory, git repo, exit status, and device.** -## Installation - -### Prerequisites - -Standard stuff: `bash(4.3+)`, `curl`, `tar`, ... - -MacOS: `coreutils` (`brew install coreutils`) - -### Simplest installation - -Run this command. +## Install with one command ```sh -curl -fsSL https://raw.githubusercontent.com/curusarn/resh/master/scripts/rawinstall.sh | bash +curl -fsSL https://raw.githubusercontent.com/curusarn/resh/master/scripts/rawinstall.sh | sh ``` -### Simple installation - -Run +You will need to have `curl` and `tar` installed. -```shell -git clone https://github.com/curusarn/resh.git -cd resh && scripts/rawinstall.sh -``` +More options on [Installation page](./installation.md) -### Update - -Check for updates and update +## Update +Once installed RESH can be updated using: ```sh reshctl update ``` -## Roadmap - -[Overview of the features of the project](./roadmap.md) - -## RESH SEARCH application +## Search your history -This is the most important part of this project. +TODO: redo this -RESH SEARCH app searches your history by commands. It uses device, directories, git remote, and exit status to show you relevant results first. +Draft: +See RESH in action - record a terminal video -All this context is not in the regular shell history. RESH records shell history with context to use it when searching. +Recording content: +Search your history by commands - Show searching some longer command -At first, the search application will look something like this. Some history with context and most of it without. As you can see, you can still search the history just fine. +Get results based on current context - Show getting project-specific commands -![resh search app](img/screen-resh-cli-v2-7-init.png) +Find any command - Show searching where the context brings the relevant command to the top -Eventually most of your history will have context and RESH SEARCH app will get more useful. +Start searching now - Show search in native shell histories -![resh search app](img/screen-resh-cli-v2-7.png) -Without a query, RESH SEARCH app shows you the latest history based on the current context (device, directory, git). +Press CTRL+R to search. +Say bye to weak standard history search. -![resh search app](img/screen-resh-cli-v2-7-no-query.png) -RESH SEARCH app replaces the standard reverse search - launch it using Ctrl+R. -Enable/disable the Ctrl+R keybinding: - -TODO: how to enable disable keybindings +TODO: This doesn't seem like the right place for keybindings ### In-app key bindings @@ -92,36 +70,8 @@ TODO: how to enable disable keybindings - Ctrl+G to abort and paste the current query onto the command line - Ctrl+R to switch between RAW and NORMAL mode -### View the recorded history - -FIXME: redo/update this section - -Resh history is saved to: `~/.resh_history.json` - -Each line is a versioned JSON that represents one executed command line. - -This is how I view it `tail -f ~/.resh_history.json | jq` or `jq < ~/.resh_history.json`. - -You can install `jq` using your favorite package manager or you can use other JSON parser to view the history. - -![screenshot](img/screen.png) - -*Recorded metadata will be reduced to only include useful information in the future.* - -## Known issues - -### Q: I use bash on macOS and resh doesn't work - -**A:** Add line `[ -f ~/.bashrc ] && . ~/.bashrc` to your `~/.bash_profile`. - -**Long Answer:** Under macOS bash shell only loads `~/.bash_profile` because every shell runs as login shell. - -## Issues and ideas - -Please do create issues if you encounter any problems or if you have suggestions: https://github.com/curusarn/resh/issues - -## Uninstallation +## Issues & Ideas -You can uninstall this project at any time by running `rm -rf ~/.resh/`. +Find help on [Troubleshooting page](./troubleshooting.md) -You won't lose any recorded history by removing `~/.resh` directory because history is saved in `~/.resh_history.json`. +Still got an issue? Create an issue: https://github.com/curusarn/resh/issues diff --git a/cmd/daemon/dump.go b/cmd/daemon/dump.go index b3a154f..d3a2e1f 100644 --- a/cmd/daemon/dump.go +++ b/cmd/daemon/dump.go @@ -2,7 +2,7 @@ package main import ( "encoding/json" - "io/ioutil" + "io" "net/http" "github.com/curusarn/resh/internal/histfile" @@ -18,7 +18,7 @@ type dumpHandler struct { func (h *dumpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { sugar := h.sugar.With(zap.String("endpoint", "/dump")) sugar.Debugw("Handling request, reading body ...") - jsn, err := ioutil.ReadAll(r.Body) + jsn, err := io.ReadAll(r.Body) if err != nil { sugar.Errorw("Error reading body", "error", err) return diff --git a/cmd/daemon/main.go b/cmd/daemon/main.go index cc0a108..01e9105 100644 --- a/cmd/daemon/main.go +++ b/cmd/daemon/main.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -22,7 +21,37 @@ var version string var commit string var development string +const helpMsg = `ERROR: resh-daemon doesn't accept any arguments + +WARNING: + You shouldn't typically need to start RESH daemon yourself. + Unless its already running, RESH daemon is started when a new terminal is opened. + RESH daemon will not start if it's already running even when you run it manually. + +USAGE: + $ resh-daemon + Runs the daemon as foreground process. You can kill it with CTRL+C. + + $ resh-daemon-start + Runs the daemon as background process detached from terminal. + +LOGS & DEBUGGING: + Logs are located in: + ${XDG_DATA_HOME}/resh/log.json (if XDG_DATA_HOME is set) + ~/.local/share/resh/log.json (otherwise - more common) + + A good way to see the logs as they are being produced is: + $ tail -f ~/.local/share/resh/log.json + +MORE INFO: + https://github.com/curusarn/resh/ +` + func main() { + if len(os.Args) > 1 { + fmt.Fprint(os.Stderr, helpMsg) + os.Exit(1) + } config, errCfg := cfg.New() logger, err := logger.New("daemon", config.LogLevel, development) if err != nil { @@ -83,7 +112,7 @@ func main() { ) } } - err = ioutil.WriteFile(pidFile, []byte(strconv.Itoa(os.Getpid())), 0644) + err = os.WriteFile(pidFile, []byte(strconv.Itoa(os.Getpid())), 0644) if err != nil { sugar.Fatalw("Could not create PID file", "error", err, @@ -116,7 +145,7 @@ type daemon struct { } func (d *daemon) killDaemon(pidFile string) error { - dat, err := ioutil.ReadFile(pidFile) + dat, err := os.ReadFile(pidFile) if err != nil { d.sugar.Errorw("Reading PID file failed", "PIDFile", pidFile, @@ -128,8 +157,7 @@ func (d *daemon) killDaemon(pidFile string) error { return fmt.Errorf("could not parse PID file contents: %w", err) } d.sugar.Infow("Successfully parsed PID", "PID", pid) - cmd := exec.Command("kill", "-s", "sigint", strconv.Itoa(pid)) - err = cmd.Run() + err = exec.Command("kill", "-SIGTERM", fmt.Sprintf("%d", pid)).Run() if err != nil { return fmt.Errorf("kill command finished with error: %w", err) } diff --git a/cmd/daemon/record.go b/cmd/daemon/record.go index 8fc6bb4..93a0dd3 100644 --- a/cmd/daemon/record.go +++ b/cmd/daemon/record.go @@ -2,7 +2,7 @@ package main import ( "encoding/json" - "io/ioutil" + "io" "net/http" "github.com/curusarn/resh/internal/recordint" @@ -28,7 +28,7 @@ func (h *recordHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { sugar := h.sugar.With(zap.String("endpoint", "/record")) sugar.Debugw("Handling request, sending response, reading body ...") w.Write([]byte("OK\n")) - jsn, err := ioutil.ReadAll(r.Body) + jsn, err := io.ReadAll(r.Body) // run rest of the handler as goroutine to prevent any hangups go func() { if err != nil { diff --git a/cmd/daemon/session-init.go b/cmd/daemon/session-init.go index 9ddd76f..86fdb92 100644 --- a/cmd/daemon/session-init.go +++ b/cmd/daemon/session-init.go @@ -2,7 +2,7 @@ package main import ( "encoding/json" - "io/ioutil" + "io" "net/http" "github.com/curusarn/resh/internal/recordint" @@ -19,7 +19,7 @@ func (h *sessionInitHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { sugar.Debugw("Handling request, sending response, reading body ...") w.Write([]byte("OK\n")) // TODO: should we somehow check for errors here? - jsn, err := ioutil.ReadAll(r.Body) + jsn, err := io.ReadAll(r.Body) // run rest of the handler as goroutine to prevent any hangups go func() { if err != nil { diff --git a/installation.md b/installation.md new file mode 100644 index 0000000..e4fbf08 --- /dev/null +++ b/installation.md @@ -0,0 +1,51 @@ +# Installation + +## One command installation + +Feel free to check the `rawinstall.sh` script before running it. + +```sh +curl -fsSL https://raw.githubusercontent.com/curusarn/resh/master/scripts/rawinstall.sh | sh +``` + +You will need to have `curl` and `tar` installed. + +## Update + +Once installed RESH can be updated using: +```sh +reshctl update +``` + +## Clone & Install + +```sh +git clone https://github.com/curusarn/resh.git +cd resh +scripts/rawinstall.sh +``` + +## Build from source + +:warning: Building from source is intended for development and troubleshooting. + +```sh +git clone https://github.com/curusarn/resh.git +cd resh +make install +``` + +## Uninstallation + +You can uninstall RESH by running: `rm -rf ~/.resh/`. +Restart your terminal after uninstall. + +### Installed files + +Binaries and shell files are in: `~/.resh/` + +Recorded history, device files, and logs are in: `~/.local/share/resh/` (or `${XDG_DATA_HOME}/resh/`) +RESH config file is in: `~/.config/resh.toml` + +Also check your `~/.zshrc` and `~/.bashrc`. +RESH adds a necessary line there to load itself on terminal startup. diff --git a/internal/histfile/histfile.go b/internal/histfile/histfile.go index d4d3a7b..cdf04f9 100644 --- a/internal/histfile/histfile.go +++ b/internal/histfile/histfile.go @@ -100,7 +100,7 @@ func (h *Histfile) loadHistory(bashHistoryPath, zshHistoryPath string, maxInitHi ) history, err := h.rio.ReadAndFixFile(h.historyPath, 3) if err != nil { - h.sugar.Panicf("Failed to read file: %w", err) + h.sugar.Fatalf("Failed to read history file: %v", err) } h.sugar.Infow("Resh history loaded from file", "historyFile", h.historyPath, @@ -113,7 +113,7 @@ func (h *Histfile) loadHistory(bashHistoryPath, zshHistoryPath string, maxInitHi h.sugar.Infow("Resh history loaded and processed", "recordCount", len(reshCmdLines.List), ) - if useNativeHistories == false { + if !useNativeHistories { h.bashCmdLines = reshCmdLines h.zshCmdLines = histlist.Copy(reshCmdLines) return diff --git a/internal/opt/opt.go b/internal/opt/opt.go index bccb6c1..efbada2 100644 --- a/internal/opt/opt.go +++ b/internal/opt/opt.go @@ -1,6 +1,7 @@ package opt import ( + "fmt" "os" "github.com/curusarn/resh/internal/output" @@ -17,10 +18,10 @@ func HandleVersionOpts(out *output.Output, args []string, version, commit string // and adding "more correct" variants would mean supporting more variants. switch os.Args[1] { case "-version": - out.Info(version) + fmt.Print(version) os.Exit(0) case "-revision": - out.Info(commit) + fmt.Print(commit) os.Exit(0) case "-requireVersion": if len(os.Args) < 3 { diff --git a/internal/recio/read.go b/internal/recio/read.go index d94af80..e88d86c 100644 --- a/internal/recio/read.go +++ b/internal/recio/read.go @@ -22,18 +22,21 @@ func (r *RecIO) ReadAndFixFile(fpath string, maxErrors int) ([]record.V1, error) numErrs := len(decodeErrs) if numErrs > maxErrors { r.sugar.Errorw("Encountered too many decoding errors", - "corruptedRecords", numErrs, + "errorsCount", numErrs, + "individualErrors", "", ) - return nil, fmt.Errorf("encountered too many decoding errors") + return nil, fmt.Errorf("encountered too many decoding errors, last error: %w", decodeErrs[len(decodeErrs)-1]) } if numErrs == 0 { return recs, nil } - // TODO: check the error messages - r.sugar.Warnw("Some history records could not be decoded - fixing resh history file by dropping them", + r.sugar.Warnw("Some history records could not be decoded - fixing RESH history file by dropping them", "corruptedRecords", numErrs, + "lastError", decodeErrs[len(decodeErrs)-1], + "individualErrors", "", ) + fpathBak := fpath + ".bak" r.sugar.Infow("Backing up current corrupted history file", "historyFileBackup", fpathBak, @@ -93,13 +96,13 @@ func (r *RecIO) ReadFile(fpath string) ([]record.V1, []error, error) { } recs = append(recs, *rec) } - r.sugar.Infow("Loaded resh history records", - "recordCount", len(recs), - ) if err != io.EOF { r.sugar.Error("Error while reading file", zap.Error(err)) return recs, decodeErrs, err } + r.sugar.Infow("Loaded resh history records", + "recordCount", len(recs), + ) return recs, decodeErrs, nil } diff --git a/internal/searchapp/test.go b/internal/searchapp/test.go deleted file mode 100644 index 52a0982..0000000 --- a/internal/searchapp/test.go +++ /dev/null @@ -1,26 +0,0 @@ -package searchapp - -import ( - "github.com/curusarn/resh/internal/histcli" - "github.com/curusarn/resh/internal/msg" - "github.com/curusarn/resh/internal/recio" - "go.uber.org/zap" -) - -// LoadHistoryFromFile ... -func LoadHistoryFromFile(sugar *zap.SugaredLogger, historyPath string, numLines int) msg.CliResponse { - rio := recio.New(sugar) - recs, _, err := rio.ReadFile(historyPath) - if err != nil { - sugar.Panicf("failed to read history file: %w", err) - } - if numLines != 0 && numLines < len(recs) { - recs = recs[:numLines] - } - cliRecords := histcli.New(sugar) - for i := len(recs) - 1; i >= 0; i-- { - rec := recs[i] - cliRecords.AddRecord(&rec) - } - return msg.CliResponse{Records: cliRecords.List} -} diff --git a/roadmap.md b/roadmap.md deleted file mode 100644 index 4bd400d..0000000 --- a/roadmap.md +++ /dev/null @@ -1,45 +0,0 @@ - -# RESH Roadmap - -| | Legend | -| --- | --- | -| :heavy_check_mark: | Implemented | -| :white_check_mark: | Implemented but I'm not happy with it | -| :x: | Not implemented | - -*NOTE: Features can change in the future* - -TODO: Update this - -- :heavy_check_mark: Record shell history with metadata - - :heavy_check_mark: save it as JSON to `~/.resh_history.json` - -- :white_check_mark: Provide an app to search the history - - :heavy_check_mark: launch with CTRL+R (enable it using `reshctl enable ctrl_r_binding_global`) - - :heavy_check_mark: search by keywords - - :heavy_check_mark: relevant results show up first based on context (host, directory, git, exit status) - - :heavy_check_mark: allow searching completely without context ("raw" mode) - - :heavy_check_mark: import and search history from before RESH was installed - - :white_check_mark: include a help with keybindings - - :x: allow listing details for individual commands - - :x: allow explicitly searching by metadata - -- :heavy_check_mark: Provide a `reshctl` utility to control and interact with the project - - :heavy_check_mark: turn on/off resh key bindings - - :heavy_check_mark: zsh completion - - :heavy_check_mark: bash completion - -- :x: Multi-device history - - :x: Synchronize recorded history between devices - - :x: Allow proxying history when ssh'ing into remote servers - -- :x: Provide a stable API to make resh extensible - -- :heavy_check_mark: Support zsh and bash - -- :heavy_check_mark: Support Linux and macOS - -- :white_check_mark: Require only essential prerequisite software - - :heavy_check_mark: Linux - - :white_check_mark: MacOS *(requires coreutils - `brew install coreutils`)* - diff --git a/scripts/install.sh b/scripts/install.sh index 2ef65b5..a0f8b14 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash - -# TODO: Swith to sh shebang? +#!/usr/bin/env sh set -euo pipefail @@ -12,11 +10,11 @@ echo echo "Checking your system ..." printf '\e[31;1m' # red color on -reset() { +cleanup() { printf '\e[0m' # reset exit } -trap reset EXIT INT TERM +trap cleanup EXIT INT TERM # /usr/bin/zsh -> zsh login_shell=$(echo "$SHELL" | rev | cut -d'/' -f1 | rev) @@ -35,9 +33,6 @@ fi # TODO: Explicitly ask users if they want to enable RESH in shells # Only offer shells with supported versions # E.g. Enable RESH in: Zsh (your login shell), Bash, Both shells -# TODO: V3: We already partially have these checks in `reshctl doctor` -# figure out if we want to redo this in v3 or not -# the login shell logic is flawed bash_version=$(bash -c 'echo ${BASH_VERSION}') bash_version_major=$(bash -c 'echo ${BASH_VERSINFO[0]}') @@ -87,28 +82,13 @@ printf '\e[0m' # reset # # shellcheck disable=2034 # read -r x -# Shutting down resh daemon ... -echo "Stopping RESH daemon ..." -pid_file="${XDG_DATA_HOME-~/.local/share}/resh/daemon.pid" -if [ ! -f "$pid_file" ]; then - # Use old pid file location - pid_file=~/.resh/resh.pid -fi - -failed_to_kill() { - # Do not print error during first installation - if [ -n "${__RESH_VERSION-}" ]; then - echo "ERROR: Failed to kill the resh-daemon - maybe it wasn't running?" - fi -} - - -if [ -f "$pid_file" ]; then - pid=$(cat "$pid_file") - kill -SIGTERM "$pid" || failed_to_kill - rm "$pid_file" +if [ -z "${__RESH_VERSION-}" ]; then + # First installation + # Stop the daemon anyway just to be sure + # But don't output anything + ./scripts/resh-daemon-stop.sh -q else - killall -SIGTERM resh-daemon || failed_to_kill + ./scripts/resh-daemon-stop.sh fi echo "Installing ..." @@ -143,6 +123,8 @@ cp -f submodules/bash-zsh-compat-widgets/bindfunc.sh ~/.resh/bindfunc.sh cp -f scripts/shellrc.sh ~/.resh/shellrc cp -f scripts/resh-daemon-start.sh ~/.resh/bin/resh-daemon-start +cp -f scripts/resh-daemon-stop.sh ~/.resh/bin/resh-daemon-stop +cp -f scripts/resh-daemon-restart.sh ~/.resh/bin/resh-daemon-restart cp -f scripts/hooks.sh ~/.resh/ cp -f scripts/rawinstall.sh ~/.resh/ @@ -161,10 +143,10 @@ if [ "$bash_ok" = 1 ]; then fi # Adding resh shellrc to .bashrc ... grep -q '[[ -f ~/.resh/shellrc ]] && source ~/.resh/shellrc' ~/.bashrc ||\ - echo -e '\n[[ -f ~/.resh/shellrc ]] && source ~/.resh/shellrc # this line was added by RESH (REcycle SHell)' >> ~/.bashrc + echo -e '\n[[ -f ~/.resh/shellrc ]] && source ~/.resh/shellrc # this line was added by RESH' >> ~/.bashrc # Adding bash-preexec to .bashrc ... grep -q '[[ -f ~/.bash-preexec.sh ]] && source ~/.bash-preexec.sh' ~/.bashrc ||\ - echo -e '\n[[ -f ~/.bash-preexec.sh ]] && source ~/.bash-preexec.sh # this line was added by RESH (REcycle SHell)' >> ~/.bashrc + echo -e '\n[[ -f ~/.bash-preexec.sh ]] && source ~/.bash-preexec.sh # this line was added by RESH' >> ~/.bashrc fi # Only add shell directives into zsh if it passed version checks @@ -172,11 +154,10 @@ if [ "$zsh_ok" = 1 ]; then # Adding resh shellrc to .zshrc ... if [ -f ~/.zshrc ]; then grep -q '[ -f ~/.resh/shellrc ] && source ~/.resh/shellrc' ~/.zshrc ||\ - echo -e '\n[ -f ~/.resh/shellrc ] && source ~/.resh/shellrc # this line was added by RESH (REcycle SHell)' >> ~/.zshrc + echo -e '\n[ -f ~/.resh/shellrc ] && source ~/.resh/shellrc # this line was added by RESH' >> ~/.zshrc fi fi -echo "Starting RESH daemon ..." ~/.resh/bin/resh-daemon-start printf ' @@ -202,18 +183,23 @@ RESH HISTORY SEARCH Searches your history by commands. Device, directories, git remote, and exit status is used to display relevant results first. - At first, RESH SEARCH will use the standard shell history without context. + At first, RESH SEARCH will use bash/zsh history without context. All history recorded from now on will have context which will be used by the RESH SEARCH. CHECK FOR UPDATES - To check for (and install) updates use reshctl command: + To check for (and install) updates use: $ reshctl update ' +# TODO: recorded history section would be better in github readme printf " RECORDED HISTORY Your resh history will be recorded to '${XDG_DATA_HOME-~/.local/share}/resh/history.reshjson' Look at it using e.g. following command (you might need to install jq) $ cat ${XDG_DATA_HOME-~/.local/share}/resh/history.reshjson | sed 's/^v[^{]*{/{/' | jq . + +LOGS + RESH logs to '${XDG_DATA_HOME-~/.local/share}/resh/log.json' + Logs are useful for troubleshooting issues. " printf ' ISSUES & FEEDBACK diff --git a/scripts/resh-daemon-restart.sh b/scripts/resh-daemon-restart.sh new file mode 100755 index 0000000..42ed161 --- /dev/null +++ b/scripts/resh-daemon-restart.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh +resh-daemon-stop "$@" +resh-daemon-start "$@" \ No newline at end of file diff --git a/scripts/resh-daemon-start.sh b/scripts/resh-daemon-start.sh index f6ae71c..ecb7543 100755 --- a/scripts/resh-daemon-start.sh +++ b/scripts/resh-daemon-start.sh @@ -1,4 +1,8 @@ -#! /usr/bin/env sh +#!/usr/bin/env sh +if [ "${1-}" != "-q" ]; then + echo "Starting RESH daemon ..." + printf "Logs are in: %s\n" "${XDG_DATA_HOME-~/.local/share}/resh/log.json" +fi # Run daemon in background - don't block # Redirect stdin, stdout, and stderr to /dev/null - detach all I/O resh-daemon /dev/null 2>/dev/null & diff --git a/scripts/resh-daemon-stop.sh b/scripts/resh-daemon-stop.sh new file mode 100755 index 0000000..742c2d3 --- /dev/null +++ b/scripts/resh-daemon-stop.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env sh + +failed_to_kill() { + [ "${1-}" != "-q" ] && echo "Failed to kill the RESH daemon - it probably isn't running" +} + +xdg_pid() { + local path="${XDG_DATA_HOME-}"/resh/daemon.pid + [ -n "${XDG_DATA_HOME-}" ] && [ -f "$path" ] || return 1 + cat "$path" +} +default_pid() { + local path=~/.local/share/resh/daemon.pid + [ -f "$path" ] || return 1 + cat "$path" +} +legacy_pid() { + local path=~/.resh/resh.pid + [ -f "$path" ] || return 1 + cat "$path" +} +pid=$(xdg_pid || default_pid || legacy_pid) + +if [ -n "$pid" ]; then + [ "${1-}" != "-q" ] && printf "Stopping RESH daemon ... (PID: %s)\n" "$pid" + kill "$pid" || failed_to_kill +else + [ "${1-}" != "-q" ] && printf "Stopping RESH daemon ...\n" + killall -q resh-daemon || failed_to_kill +fi + diff --git a/scripts/shellrc.sh b/scripts/shellrc.sh index a641d6d..b6a0298 100644 --- a/scripts/shellrc.sh +++ b/scripts/shellrc.sh @@ -17,7 +17,7 @@ fi # shellcheck disable=2155 export __RESH_VERSION=$(resh-collect -version) -resh-daemon-start +resh-daemon-start -q [ "$(resh-config --key BindControlR)" = true ] && __resh_bind_control_R diff --git a/scripts/test.sh b/scripts/test.sh index bd2c810..c783d8c 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -1,9 +1,6 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh # very simple tests to catch simple errors in scripts -# shellcheck disable=SC2016 -[ "${BASH_SOURCE[0]}" != "scripts/test.sh" ] && echo 'Run this script using `make test`' && exit 1 - for f in scripts/*.sh; do echo "Running shellcheck on $f ..." shellcheck "$f" --shell=bash --severity=error || exit 1 @@ -14,7 +11,7 @@ for f in scripts/{shellrc,hooks}.sh; do ! zsh -n "$f" && echo "Zsh syntax check failed!" && exit 1 done -if [ "$1" == "--all" ]; then +if [ "$1" = "--all" ]; then for sh in bash zsh; do echo "Running functions in scripts/shellrc.sh using $sh ..." ! $sh -c ". scripts/shellrc.sh; __resh_preexec; __resh_precmd" && echo "Error while running functions!" && exit 1 diff --git a/troubleshooting.md b/troubleshooting.md new file mode 100644 index 0000000..dbefff7 --- /dev/null +++ b/troubleshooting.md @@ -0,0 +1,45 @@ +# Troubleshooting + +## First help + +Run RESH doctor to detect common issues: +```sh +reshctl doctor +``` + +## Restarting RESH daemon + +Sometimes restarting RESH daemon can help: +```sh +resh-daemon-restart +``` + +Two more useful commands: +```sh +resh-daemon-start +resh-daemon-stop +``` + +:warning: You will get error messages in your shell when RESH daemon is not running. + +## Logs + + + +## Disabling RESH + +If you have a persistent issue with RESH you can temporarily disable it. + +Go to `~/.zshrc` and `~/.bashrc` and comment out following lines: +```sh +[[ -f ~/.resh/shellrc ]] && source ~/.resh/shellrc +[[ -f ~/.bash-preexec.sh ]] && source ~/.bash-preexec.sh # bashrc only +``` +The second line is bash-specific so you won't find it in `~/.zshrc` + + +### RESH in bash on macOS doesn't work + +**A:** Add line `[ -f ~/.bashrc ] && . ~/.bashrc` to your `~/.bash_profile`. + +**Long Answer:** Under macOS bash shell only loads `~/.bash_profile` because every shell runs as login shell.