Is there a text editor that can run shell scripts?

I will often change a small script in gedit and then run it from a terminal. Isn't there a simple text editor with a "Run" button or something to streamline this? Even in Eclipse it's not trivial. I'm looking for specific suggestions on which text editors support this or how they can be extended to support this.


Solution 1:

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.

Update: since I wrote this answer, I have updated my own version many times with new features and broader support. Here's a link to GitHub page for this shell script. You can also see more details on the Readme page.

Solution 2:

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