36

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.

  • 5
    Possible duplicate of How to activate the Gedit terminal plugin? – karel Nov 13 at 11:56
  • 8
    Geany has an 'Execute' button, also F5 key for the same purpose. This works for scripts on my system... – andrew.46 Nov 13 at 11:58
  • 9
    @andrew.46 why you are not posting it as an answer then : ) – αғsнιη Nov 13 at 12:01
  • 3
    Geany can batch edit 50 html files at the same time and even open them all at the same time in a web browser to view the changes. Geany is that lightweight. – karel Nov 13 at 12:08
  • 8
    While editing using vim, hit Esc and type :sh and Enter, when done hit Ctrl-D and you'll get back to your vim session. – Yaron Nov 13 at 12:14

12 Answers 12

17

From:

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:

  • This is a horridly complicated solution. gVim is easier: :term for a terminal window. :! to run a single command. (shell completion and multi-tab is built-in to vim) – noɥʇʎԀʎzɐɹƆ Nov 16 at 2:27
  • @noɥʇʎԀʎzɐɹƆ How is it complicated? You press Ctrl+F9. Then you can resize your window to split size of your gedit source code and your gnome-terminal output. The installation instructions don't have to be repeated every time before you press Ctrl+F9 if that is what you are thinking. – WinEunuuchs2Unix Nov 16 at 2:30
33

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.

  • 5
    In vim, you can do :w !bash so it works even if the buffer is not saved or does not even have a filename. – JoL Nov 14 at 1:26
  • @JoL Does that write the file as an input stream to the bash executable? I can see how it could be useful (more than just running the file). – John Hamilton Nov 14 at 8:24
  • 1
    @JohnHamilton Yes, it pipes the contents of the buffer to the stdin of the command. There's also :r !cmd to read the stdout of a command into the buffer. – JoL Nov 14 at 16:36
  • Or in vim, pass the current filename to bash: :!bash % -- see :help :! – glenn jackman Nov 15 at 17:33
13

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.

8

In Emacs you can use Ctrl-C Ctrl-X for that.

8

You can use Kate, it needs konsole to work:

sudo apt install kate konsole

Then in:

Kate ⇒ Configure ⇒ Application ⇒ Plugins and check the Terminal tool view checkbox.

enter image description here

enter image description here

6

One excellent option is to use my constant companion, the text editor Geany. By default there is an 'Execute' button which is also tied by default to the key F5 that runs shell scripts from within the main editor window.

Here is a screenshot of Geany running a simple update script after it has been edited:

enter image description here

Observe as well the 'Tree Browser' plugin for Geany at the left of the screen which facilitates the selection of all of the scripts in my ~/bin folder.

5

Atom + script

You could use Atom with the script package. Once it's set up, simply press F5 (with nothing selected) to run the script based on the shebang. Then press Esc to close the output pane.*

Atom is not super lightweight, but it's also not super heavy. It also offers other packages like linter-shellcheck to help with writing and debugging code. script also supports many other languages including Python, Perl, and HTML.

To install Atom, use the official .deb installer of the latest release.


*As of 13 Nov 2019, script is experiencing a major bug where the output pane doesn't close, but the previous version is unaffected. To install the previous version:

apm install script@3.18
  • I looked all over the Atom web site, and nowhere could I find what Atom actually is. – RonJohn Nov 15 at 13:59
  • @RonJohn Oh, it says it right on the main page: "A hackable text editor for the 21st Century" – wjandrea Nov 15 at 15:23
  • You'd think they'd put that at the top instead of "below the fold". Thanks for the tip. – RonJohn Nov 15 at 15:40
5

I am not exactly sure what specific shell commands you need to run, but Visual Studio Code is becoming the current standard for a lightweight IDE.

A quick search brings me this: https://www.reddit.com/r/vscode/comments/9qbbcs/is_there_a_way_to_run_a_bash_scriptcommand_from/

Where somebody asked:

Is there a way to run a bash script/command from VS Code?

With the answers being:

A) https://code.visualstudio.com/docs/editor/tasks Yes, you can set up tasks. You can also specify a particular as the default build task

B) Code has a command prompt built in.

Later one for the case that all you're looking for is an integrated shell where you can just type ./script.sh


I scrolled through all the other answers and don't really agree. Sure, people that are used to their respective editors (vim, emacs, vi, gedit, notepad++, Atom, etc) will always point you towards their favorite.

But from multiple years in the coding industry and having tested out a lot of the newer editors, such as Atom, Sublime Text, etc. VS Code just shines through. It is what Atom always wanted to be.

It's tiny, fast, cross-platform, extensible, and almost fully customizable to your likings. If you want to be able to deliver fast results in a very productive, fun and welcoming personal environment, VS Code is my definite recommendation for you.

It's from the era where microsoft flicked a big switch in their organisation, targeting open-source, cross-platform and a much more friendly attitude towards foreign systems. And it's damn noticable the people working on the editor have had some shitty experiences with their predecessing tools of choice and decided to make those things better from scratch.

Oh yeah. It's also free.

https://code.visualstudio.com/

  • Thanks. For an IDE I'm still sticking with Eclipse, mainly because of the dead simple way I can reference Python projects there (also habit, FLOSS...). I've tried twice to migrate to VS Code and it is a sleek piece of software for sure. Everything makes sense! However for simply changing a path in a script and running it, I'd still prefer gedit with its ~3 buttons. – smcs Nov 14 at 14:27
4

Under vim/gvim, autocommands (autocmd-use) are useful for this kind of workflow such that vim (and so shell) commands can be run on specific file/buffer events - avoiding the step of you having to trigger them manually.

As an example

:au BufWritePost,FileWritePost * silent :!( cd /path/to/somewhere && ./my-shell-command with some args; )

This runs ./my-shell-command ... every time you write out/save the file. The caveat is that the output is not seen in the editor itself (as this requires a separate shell window). This may or may not be what you need.

Extending the concept to make it useful (making use of vim-tmux for e.g. to hold the stdout/stderr output), the above would become something like so

:au BufWritePost,FileWritePost * silent :Tmux ( cd /path/to/somewhere && bats my-tests.bats && ./my-script with some args; )

which personally is quite powerful if most of the workflow can be automated (code, test, run, repeat) so that you just focus on the task of writing the code.

4

I use sublime as my main text editor and never had to use a build command in there but you can use its build system to run the bash file.

I can't test this exact command right now as I'm on Windows, but this should do the job (Source):

Open the command palette (usually Ctrl-Shift-P, or under Tools menu). Choose "Build: New Build System".

Replace file contents with:

{
    "cmd"       : ["bash", "$file"],
    "selector"  : "source.shell" 
} 

Save it as bash.sublime-build in the suggested directory, which should be anywhere in Sublime's Packages directory.

Then all you need to do is press Ctrl-B to "build" your bash file (yeah, you're actually just running it).

Some explanation, "cmd" portion is the actual command that is run, you can run any command with any parameter that Sublime supports. The second part, "selector", is what file types this build system will be run for, which is just "shell" files.

0

Emacs has these shell-related functions: (NOTE: There is a learning curve with Emacs)

async-shell-command       M-&
   Execute string COMMAND asynchronously in background.
compilation-shell-minor-mode  M-x ... RET
   Toggle Compilation Shell minor mode.
eshell                M-x ... RET
   Create an interactive Eshell buffer.
eshell-command            M-x ... RET
   Execute the Eshell command string COMMAND.
eshell-mode           M-x ... RET
   Emacs shell interactive mode.
eshell-report-bug         M-x ... RET
   Report a bug in GNU Emacs.
gdb-shell-minor-mode          M-x ... RET
   Minor mode to add gdb features to shell mode.
idlwave-shell             M-x ... RET
   Run an inferior IDL, with I/O through buffer
   `(idlwave-shell-buffer)'.
minibuffer-default-add-shell-commands M-x ... RET
   Return a list of all commands associated with the current file.
shell                 M-x ... RET
   Run an inferior shell, with I/O through BUFFER (which defaults to
   `*shell*').
shell-command             <menu-bar> <tools> <shell>, M-!
   Execute string COMMAND in inferior shell; display output, if any.
shell-command-on-region       <menu-bar> <tools> <shell-on-region>, M-|
   Execute string COMMAND in inferior shell with region as input.
shell-current-directory       M-x ... RET
   Create a shell pertaining to the current directory.
shell-script-mode         M-x ... RET
   Major mode for editing shell scripts.

Or, you could use make, also with a learning curve.

0

While editing using vim, hit Esc and type :sh and Enter, when done hit Ctrl-D and you'll get back to your vim session.

Thank you all.

Not the answer you're looking for? Browse other questions tagged or ask your own question.