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.
12 Answers
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:
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 withmktemp -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.
-
5In vim, you can do
:w !bash
so it works even if the buffer is not saved or does not even have a filename.– JoLNov 14, 2019 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). Nov 14, 2019 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.– JoLNov 14, 2019 at 16:36 -
Or in vim, pass the current filename to bash:
:!bash %
-- see:help :!
Nov 15, 2019 at 17:33
From:
Gedit Plug-ins
Use gedit
external terminal plug-in
You can use gedit
with terminal plugin. The steps are fairly straight-forward:
- Enable "Universe" repository
- Install
gedit-plugins
- Activate "Embedded Terminal"
- Use Ctrl+F9 to open terminal
- 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:
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
:
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.
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
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) Nov 16, 2019 at 2:27 -
1@noɥʇʎԀʎzɐɹƆ How is it complicated? You press
Ctrl
+F9
. Then you can resize your window to split size of yourgedit
source code and yourgnome-terminal
output. The installation instructions don't have to be repeated every time before you pressCtrl
+F9
if that is what you are thinking. Nov 16, 2019 at 2:30 -
-
1@Nip If I understand your question correctly... Highlight line of code and press
Ctrl
+C
. Then move cursor to command entry line and pressCtrl
+V
followed byEnter
. Nov 5, 2020 at 0:34 -
Yes. But I was thinking in a way other than copy&paste. Something like when we press
Ctrl+R
to run a line in RGUI (windows 10).– NipNov 5, 2020 at 1:58
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.
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.
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:
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.
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, where somebody asked, "Is there a way to run a bash script/command from VS Code?" (2018-10-22), with the answers being:
https://code.visualstudio.com/docs/editor/tasks
Yes, you can set up tasks. You can also specify a particular as the default build task
Code has a command prompt built in.
-- /u/cornystool - permalink
Later on 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.
-
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.– smcsNov 14, 2019 at 14:27
Atom + script
You could use Atom editor with the script
package. Once you set it up, simply press F5 (with nothing selected) to run the script. It will use the shebang to determine what interpreter to run. 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.
script-runner
Alternatively, the script-runner
package works similarly to script
, but features a full terminal, so you can provide input on stdin for example. Press Alt+X to start it, then close the pane when you're done.
Hydrogen
Just to mention, for more programming-type stuff, Hydrogen can be used to run code interactively, just like Jupyter.
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.
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.
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.
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.
vim
, hitEsc
and type:sh
and Enter, when done hitCtrl-D
and you'll get back to yourvim
session.