Is there a text editor that can run shell scripts?

Option 1: use vim, emacs, geany, and many more!

In vim and use :!bash file.sh or just create a shortcut for it in .vimrc

In Emacs, you use M-!. So you hold down Alt and then press !. You can even pass text in your current buffer to a command by selecting what you want to pass to a command and then pressing M-|. So you can highlight your code and pass it to the command bash.

Every tool has it's own way!

Option 2: use find and entr

Run this command so whenever ANY .sh file in the directory changes, it'll be run again automatically:

find . -name '*.sh' | entr -cs file.sh

Option 3: use combination of tmux, vim, and entr for live coding

I wrote this long ago for c++ and then used it more in other languages and now you can use it for shell programming as well.

Here's how it'll look like:

cppshell

for the program to run all I have to do is to save it in vim (:w) and it'll run.

Save this in ~/bin/ide:

#!/usr/bin/bash

tmpdir=""
template="simple"

for i in "$@"
do
case $i in
    -t=*|--template=*)
        template="${i#*=}"
    shift # past argument=value
    ;;

    -n=*|--name=*)
    dir="${i#*=}"
    mkdir -p ~/cppshells/$dir
    tmpdir=~/cppshells/$dir
    shift
    ;;

    -h|--help)
    echo "-n=*|--name=* \t\t the name of the project"
    echo "-t=*|--template \t\t the template to use"
    exit;
    ;;


    *)
        # nothing to do
    ;;
esac
done

if [ -z "$tmpdir" ]; then
    tmpdir=$(mktemp -d)
fi;

tmpdir=$(realpath ${tmpdir});
window="cpp-$1-$((1 + RANDOM % 10000000))"

if [ -z "$EDITOR" ]; then
    EDITOR="nvim";
fi;

template_dir="$(dirname $0)/templates/${template}"

if [ ! -d $template_dir ]; then
    echo "The specified template ($template) does not exists."
    exit;
fi;

tmux new -s ${window} -d -c "${tmpdir}"
tmux split-window -t ${window} -h
tmux select-pane -t ${window}.right
tmux resize-pane -t ${window}.right -R 18
tmux send-keys -t ${window}.left "cd ${tmpdir}" C-m
tmux send-keys -t ${window}.right "cd ${tmpdir}" C-m


# copy files if the directory does not exists
if [ `ls -A ${tmpdir} | wc -m` == "0" ]; then
    cp -nr $template_dir/* ${tmpdir}/.
fi;

# run build commands
if [ -f ${template_dir}/Makefile ]; then # make
    tmux send-keys -t ${window}.right "find . -name '*.cpp' | entr -cs 'make -j8 && ./a.out'" C-m
        tmux send-keys -t ${window}.left "${EDITOR} ${tmpdir}/main.cpp" C-m
elif [ -f ${template_dir}/CMakeLists.txt ]; then # CMake
    mkdir -p ${tmpdir}/build
    cmake -G "Unix Makefiles" -B${tmpdir}/build -S${tmpdir}
    tmux send-keys -t ${window}.right "find . -name '*.cpp' | entr -cs 'make -j8 -Cbuild/ && ./build/a.out'" C-m
        tmux send-keys -t ${window}.left "${EDITOR} ${tmpdir}/main.cpp" C-m
elif [ -f ${template_dir}/main.py ]; then # Python
        chmod +x ${tmpdir}/main.py
    tmux send-keys -t ${window}.right "find . -name 'main.py' | entr -cs '${tmpdir}/main.py'" C-m
        tmux send-keys -t ${window}.left "${EDITOR} ${tmpdir}/main.py" C-m
elif [ -f ${template_dir}/main.sh ]; then # Bash
        chmod +x ${tmpdir}/main.sh
    tmux send-keys -t ${window}.right "find . -name 'main.sh' | entr -cs '${tmpdir}/main.sh'" C-m
        tmux send-keys -t ${window}.left "${EDITOR} ${tmpdir}/main.sh" C-m
fi;


tmux select-pane -t ${window}.left
tmux attach -t ${window}

Then create ~/bin/templates/simple directories and put a simple main.sh file in them which will be your starting point when you run ide command. You can also create more and more templates (each one in a different directory in ~/bin/templates/ directory).

Add /home/$USER/bin to your path so you can run ide.

To run the script you can use these 3 ways:

  • For simple tests: ide (it'll create a temp directory with mktemp -d command
  • To save the file in ~/cppshell/[something]/ dir: ide -n=something
  • To use a different template(starting point): ide -t=not-simple -n=some_name

As I said you could use this script to make shell like tool for running python, C++, bash, or even add your own.


From:

  • How to debug c programs by gedit?

Gedit Plug-ins

Use gedit external terminal plug-in

You can use gedit with terminal plugin. The steps are fairly straight-forward:

  1. Enable "Universe" repository
  2. Install gedit-plugins
  3. Activate "Embedded Terminal"
  4. Use Ctrl+F9 to open terminal
  5. Other gedit plug-ins

Step 1. Enable "Universe" repository

The first step is to ensure Universe repository is activated from Settings->Software & Updates->Ubuntu Software and ensure the third option is checked:

gedit plugins repository.png

Step 2. Install gedit-plugins

Install gedit-plugs with the command:

sudo apt install gedit-plugins

Step 3. Activate "Embedded Terminal"

Open gedit (don't use sudo) and select Edit->Preferences->Plugins and check off Embedded Terminal:

gedit embedded terminal.png

Step 4. Use Ctrl+F9 to open terminal

In the GIF below we use Ctrl+F9 to get a tiny window with the command prompt. Use the mouse to drag the dividing line up.

gedit terminal plugin.gif

Step 5. Other gedit plug-ins

As mentioned in Step 4., you can grab the separator bar to make the terminal window bigger. Here's what it looks like in a normal picture ((not a GIF).

There are three other plug-ins I currently use in the gedit coding window:

  • plug-in to display 80 character cut-off with different background color
  • plug-in to display entire document in thumbnail you can drag to quickly go to code section
  • Highlight matching brackets

gedit teriminal line wrap.png

For further reading please see:

  • Code completion for gedit
  • Useful Gedit plugins for programmers - HowtoForge
  • gedit: Add Python / C++ Autocomplete Support - nixCraft
  • 5 Must-Have Gedit Plugins for Programmers | Yaser Sulaiman's Blog
  • How to C program in gedit - Quora

If you're comfortable with vim, you can execute

:w !bash

(sub your shell of choice) and that will execute the script in the current buffer.

In a graphical environment, I use VS Code. It's a lightweight IDE that's extensible, has built-in GIT support, and an integrated terminal.