or, how to become the UNIXMENSCH

Why not graphical IDEs?

Very frequently people ask me why I don't just use Visual Studio, Jetbrains, Sublime or (not so much recently) Atom. My answer is a mumbling grumble of nonfree inefficient POSIX noncompliant anti ergonomic webshit. I would like to elaborate on this nonsense and demonstrate how the UNIX operating system is designed to be an integrated development environment.

Every UNIX system comes with all the tools necessary to write, develop, and deploy software. Nearly all systems come with an editor, a compiler, debugger, various scripting languages, automation tools, etc. If the base system does not come with these tools, they will always be trivially installable using a package or ports management system. Choosing to use the terminal as your development environment is the only worthwhile investment. Graphical tools are transient, POSIX is forever.

POSIX is the lowest common denominator

The UNIX 'IDE' is the most widely supported environment in the world. Every UNIX system comes with a set of common programs in accordance to the POSIX standard. The POSIX standard was created in order to assure a common programming interface between various implementations of UNIX. The user interfaces across this wide array of operating systems are nearly identical because the shell is an interpreter (ie a programming language).

Using the terminal as the primary user interface increases productivity. Tasks can be performed at the speed of thought. Tasks that are performed more than once are quickly and easily scriptable. Every 'plugin' you choose to install is directly compatible with every other 'plugin' on your system by virtue of pipes.

The flexibility provided by pipes means that the shell user has absolute control over their environment. The shell is unwavering. Never again will the humble UNIXMENSCH be forced into re-learning his tools at the flippant whims of UI/UX designers who are inexcusably convinced that destroying existing paradigms is integral to the success of their product. Everywhere the UNIXMENSCH goes, he knows that he will instantly be productive and competent with the available tools. The UNIXMENSCH is resistant to planned obsolesce, vendor dependency, hardware constraints, and restrictions placed by the owner of the system. The UNIXMENSCH transcends the childish desire for clicky buttons and unnecessary 'features'. He knows that his skills will never be deprecated because he chose to invest in the LCD.

Compatibility issues with graphical editors

The table below demonstrates the availability of a UNIX environment on a set of given operating systems. All of the graphical IDEs are limited to a small set of operating systems and architectures. Typically, only amd64 Windows and amd64 MacOS are supported. If Linux is supported, it's only a small set of distributions limited to Ubuntu (if the company uses Linux internally), RHEL variants (if the current UTC timestamp is a prime number), and SUSE (but only because sometimes it's possible to install a .rpm built for RHEL).

The UNIX column exists to demonstrate that the UNIX 'IDE' is available and fully functional on nearly every operating system. It does not contain information about architecture support. If the operating system will run on $(uname -p), that operating system has a fully functional environment. If it won't run, try NetBSD.

  UNIX Sublime Eclipse Atom Visual Studio Jetbrains
GNU/Linux (distro dependent, amd64 and arm64 only) (distro, JVM, and architecture dependent) (distro dependent, not in repos, amd64 only) (distro dependent, not in repos, amd64 arm and arm64 only) (distro and architecture dependent, not in repos)
Windows (with cygwin)
MacOS
FreeBSD (unofficial, architecture dependent, requires a linux compat layer) (unofficial, amd64 an ppc64 archs only) (unofficial, amd64 only, marked as deprecated and broken as of writing) (unofficial, architecture dependent. Only clion, datagrip, goland, phpstorm, and webstorm)
OpenBSD
NetBSD
DragonflyBSD
Solaris
illumos
Haiku
AIX
HP-UX
Redox
z/OS
Plan 9 (with vt(1) and ape)
MINIX

In summary, the UNIX 'IDE' is the only 'IDE' that is available everywhere. For the other IDEs, the fact that they are not available in the software repositories is telling. Why can't I install this IDE with my package manager? There are a few reasons:

It's not free software

Some software is not truly free software even if it has an open core. The Fedora project's packaging guidelines are as follows:

Not everything can be packaged in Fedora. Most things considered to be "free software" or "open source software" are permitted, but definitions of these are not always consistent and Fedora has a few specific requirements and exceptions.
Some software (or in some cases, portions of that software) cannot be packaged for legal reasons. This includes issues related to licensing, patents, trademark law, etc.

Nobody wanted it

Why work on a port if no one wants it or no one uses it? From OpenBSD:

People often ask why a particular product is or isn't included with OpenBSD. The answer is based on two things: the wishes of the developers and compatibility with the goals of the project. A product will not be included simply because it is "neat" -- it must also be "free" for use, distribution and modification by our standards. A product must also be stable and secure -- a bigger version number does not always mean a better product.
License is often the biggest problem: we want OpenBSD to remain usable by any person anywhere in the world for any purpose.
Another major consideration is the wishes of the developers. The OpenBSD developers are the ultimate judges of what does and doesn't go into the project. Just because an application is "good" doesn't mean the OpenBSD project wishes to devote the resources needed to maintaining it, or that they will share other's enthusiasm about its place in OpenBSD.

Nobody wrote the code

Porting software is difficult. Porting software written for a specific operating system with the explicit purpose of being as difficult to port as possible is even harder. Writing shims to support alternative nonfree programs is largely considered a waste of time. Why try to port or write shims to support garbage software when the native thing we already have is better? From 9front:

Many "features" and programs are missing from Plan 9 for a very good reason: They are terrible ideas expressed as terrible software. Other features are missing simply because no one has yet written the code to implement them. It is left as an exercise for the reader to determine which is which, and to apply the appropriate remedy.

Other issues with graphical editors

Most of the 'professional' graphical editors are nonfree. This means that they are not open source or they contain some component that prevents users from redistributing the software. A typical example is Google Chrome. The core might be free software but to redistribute it would be a crime. If the branding is intellectual property, the software is not freely redistributable.

Most of the 'free' editors are webshit built on top of Google Chrome. This is a massive liability. Chrome is spyware. Even though chrome is open source, it's too large and moves too quickly to guarantee any safety through an audit process. Since the core of these IDEs is developed by a company that is hellbent on sucking up every bit of data it can. This is absolutely unacceptable. The fact that these glorified text editors now have the ability to spy on users should make any competent computer user quake in their boots.

All of the graphical editors in the table above are owned by companies that do not value or are actively hostile to free software. I can't speak for the non-Microsoft companies but all proprietary software is inherently unethical and malicious. For the Microsoft owned editors (visual studio and atom via the github acquisition), the company has an overwhelming history of active hostility towards open source. The worst thing a person can do to themselves is depend on software sponsored by a company that has a reputation of attacking free software (or is actively resistant to open sourcing the majority of their products).

In addition to the harms caused by the producers of graphical editors, the graphical editors are designed to restrict and infantilize users. Rather than gain independence and self sufficiency, the graphical IDE user prefers to remain ignorant of the underlying system. If the IDE disappears, the user is left helpless. The average IDE user is incapable of quickly building an entire web browser with a thousand 'features' that require millions of dollars and thousands of hours to develop. They will never recover their golden calf of a 'workflow'.

To contrast: If, for some reason, UNIX and UNIX like operating systems ceased to exist, the average hobbyist programmer could hack together a POSIX-ish userland. Even if the kernel remains nonfree, this hobbyist could quickly create the full suite of POSIX tools. Within a few weeks, the hobbyist has resumed his initial work.

The nonfree and unautidable graphical IDE is harmful in all aspects. If not to the freedom and integrity of the operating system, to the mind of the user.

The terminal workflow

Now that I have completely and thoroughly exhausted my frustrations with the concept the IDE, I can proceed with real world examples of using the terminal as a workflow. I will discuss editors, multiplexers, and methods for getting the most out of the shell.

Editors

Although ed(1) is the standard editor, it might be too brutalist for the user pursuing the path of the UNIXMENSCH. I prefer vim, but vi(1) comes with most UNIX operating systems. Some people prefer emacs but I don't recommend this as emacs is not POSIX compliant and doesn't work well on remote systems without X11 forwarding.

If emacs is used, it can be started with the -nw flag. Since tmux uses a prefix key, you can send C-b to emacs by typing it twice. Remapping would also work.

Vi is a modal editor. Vi starts in the normal mode. This mode is used for navigation and manipulating text. When a key is pressed in normal mode, vi enters insert mode. Insert mode is used for inserting text. There is also command mode. Vim has additional modes that build upon the traditional vi modes.

The vimtutor command does what it says: opens a vim tutorial. See also:

$ vimtutor
$ man vi

File managers

Vim has a built in file browser. Many UNIXMENSCH choose to use the ranger or mc programs. I prefer ol' reliable. tui interfaces are largely unnecessary when we have commands like ls, pwd, cp, rm, and mv. To find out more, see:

$ man intro
$ man builtins

Multiplexers

Is that it? Editing text? I need more tabs!! The tmux command is a terminal multiplexer. Tmux comes with a base OpenBSD installation and can easily be installed on other operating systems. Ancient GNU systems might come with screen but this program is incredibly unpleasant to use.

Tmux is capable of detached and nested sessions. Tmux is resistant to X11 crashes and dropped network connections. Each 'session' can contain it's own environment. We can customize each of these sessions to fit our specific languages. If you need more help, see:

$ man tmux

here are the default tmux keybindings. The semantics is similar to emacs. The C- means "press the control key at the same time as the key after the dash". The M- means "press the meta (alt) key at the same time as the key after the dash".

Each command is ran by first typing the prefix combination, releasing the prefix keys, then typing the corresponding command key. For example: to detach a session, run C-b d. To add a window, run C-b c

C-b Send the prefix key (C-b) through to the application.
C-o Rotate the panes in the current window forwards.
C-z Suspend the tmux client.
! Break the current pane out of the window.
" Split the current pane into two, top and bottom.
# List all paste buffers.
$ Rename the current session.
% Split the current pane into two, left and right.
& Kill the current window.
' Prompt for a window index to select.
( Switch the attached client to the previous session.
) Switch the attached client to the next session.
, Rename the current window.
- Delete the most recently copied buffer of text.
. Prompt for an index to move the current window.
0 to 9 Select windows 0 to 9.
: Enter the tmux command prompt.
; Move to the previously active pane.
= Choose which buffer to paste interactively from a list.
? List all key bindings.
D Choose a client to detach.
L Switch the attached client back to the last session.
[ Enter copy mode to copy text or view the history.
] Paste the most recently copied buffer of text.
c Create a new window.
d Detach the current client.
f Prompt to search for text in open windows.
i Display some information about the current window.
l Move to the previously selected window.
m Mark the current pane (see select-pane -m).
M Clear the marked pane.
n Change to the next window.
o Select the next pane in the current window.
p Change to the previous window.
q Briefly display pane indexes.
r Force redraw of the attached client.
s Select a new session for the attached client interactively.
t Show the time.
w Choose the current window interactively.
x Kill the current pane.
z Toggle zoom state of the current pane.
{ Swap the current pane with the previous pane.
} Swap the current pane with the next pane.
~ Show previous messages from tmux, if any.
Page Up Enter copy mode and scroll one page up.
Up, Down, Left, Right Change to the pane above, below, to the left, or to the right of the current pane.
M-1 to M- Arrange panes in one of the five preset layouts: even-horizontal, even-vertical, main-horizontal, main-verti‐cal, or tiled.
Space Arrange the current window in the next preset layout.
M-n Move to the next window with a bell or activity marker.
M-o Rotate the panes in the current window backwards.
M-p Move to the previous window with a bell or activity marker.
C-Up, C-Down, C-Left, C-Right Resize the current pane in steps of one cell.
M-Up, M-Down ,M-Left, M-Right Resize the current pane in steps of five cells.

Sample tmux scripts

This tmux session will start a PHP dev server, a shell, an editor, filemanager, sftp connection, and web browser at startup time.

#!/bin/sh

cd ~/src/mysite

# check if php session exists
tmux has-session -t php &> /dev/null

# if php sesison does not exist, create it
if [ $? -ne 0 ]
then
	tmux new-session -s php -n script -d -n "testserver" "php -S localhost:8080"
	tmux new-window -d -n "shell" 	$SHELL
	tmux new-window -d -n "editor"  "vim ./"
	tmux new-window -d -n "files"  	"mc ./"
	tmux new-window -d -n "remote"  "sftp webmaster@my-server.tld"
	tmux new-window -d -n "www" 	"w3m http://localhost:8080"
fi

# attach session
tmux attach -t php

This C session opens various tmux windows and includes split panes, one for the editor and one for the debugger. This is most powerful when combined with a makefile.

#!/bin/sh

cd ~/src/

# check if c session exists
tmux has-session -t c &> /dev/null

# if php sesison does not exist, create it
if [ $? -ne 0 ]
then
	tmux new-session  -s c -n script -d -n "manpages"
	tmux new-window   -d -n "shell" 	"$SHELL"
	tmux new-window   -d -n "editor"  	"vim ./"
	tmux split-window -d    		"gdb"
	tmux new-window   -d -n "mkdb"  	"$SHELL"
fi

# attach session
tmux attach -t c

This tmux session will ssh into all of your servers, each in their own pane. This is useful for checking stats. Since tmux sessions can be nested, you can log in to your remote server and re-attach a long running process.

#!/bin/sh

cd ~/src/

# check if php session exists
tmux has-session -t servers &> /dev/null

# if php sesison does not exist, create it
if [ $? -ne 0 ]
then
	tmux new-session -s servers -n script -d -n "freebsd" "ssh sysadmin@my-domain.tld 'zpool list && zfs list'"
	tmux split-window -d  "freebsd" "ssh sysadmin@my-domain"
	tmux new-window -d -n "linux" 	"ssh sysadmin@my-other-domain 'top'"
	tmux split-window -d  "linux" 	"ssh sysadmin@my-domain"
fi

# attach session
tmux attach -t servers 

A graphical window with 50 tabs and 45 different buttons that all do basically the same thing is unnecessary. Minimalism == productivity.

Making the scripts easy to use

~/bin or ~/.local/bin is where these short shell scripts should go. This should be added to the shell's $PATH variable. This is shell dependent. In bash, it's simple.

$ echo PATH=\$PATH:~/bin >> ~/.bashrc
$ source ~/.bashrc

Now, to make these scripts executable

$ cd ~/bin
$ chmod a+x ./php-tmuxsession.sh
$ chmod a+x ./c-tmuxsession.sh
$ chmod a+x ./servers-tmuxsession.sh

Many users choose to create aliases but I prefer to keep my shell as vanilla as possible to avoid name collisions.

Makefiles

Makefiles are an easy way to create a terminal 'IDE' without a multiplexer. Makefiles also make it easier to build, test, debug, and deploy code written inside of a tmux session.

Here is a bare bones makefile. As scope increases, more targets can easily be added to the makefile. Although this makefile is specific to C programming, a makefile with targets such as serve, make-tarball, generate-patch, etc are all very easy to write and use.

build:
	cc main.c -o main

run: build
	./main

debug: 
	cc -g main.c -o main && gdb ./main

memtest: build
	valgrind ./main

edit: 
	vim main.c

emergencypush:
	git add . && git commit -m "emergency push, building is on fire" && git push

To use the makefile from within vi, enter command mode in vi and type :! make $target. Once the processes started by the makefile are complete, you will be able to review the output or interact with the debugger then be placed back into vi.

A graphical menu with 30 different ways to compile and run a program is unnecessary. A 10 line makefile is more efficient and intuitive to use.

Adding 'plugins'

There is no such thing as 'plugins' for the terminal environment. Every component is modular. Any functionality a user could ever want is available in the software repository.

There are, however, many plugins for vim that might be of interest. vim-syntastic is useful for people who are too lazy to run a program to find errors or are hopelessly dependent on their IDE doing all of the actual programming work for them. Syntastic is described as follows:

Description: Syntastic is a syntax checking plugin that runs files through external syntax checkers and displays any resulting errors to the user. This can be done on demand, or automatically as files are saved. If syntax errors are detected, the user is notified and is happy because they didn't have to compile their code or execute their script to find them.

Nearly all programming languages are supported in a default installation of vim. Even if a language is not supported, vim will still attempt to apply syntax highlighting and autoindent rules.

Many users also choose to use vim-airline plugin because they like extremely ugly blocks of neon colors at the bottom of their terminal. It adds no functionality whatsoever because stock vim already supports multiple windows and panes.

Vim comes with autocomplete out of the box. Typing C-n will display a menu. There are many other plugins that change the appearance of this functionality but those are largely unnecessary.

I typically prefer to keep my editor as vanilla as possible. I can't take my extremely custom configurations with me to every server I might ever visit. Adding excessive plugins can also slow vim down. The general attitude is Learn the defaults first because plugins oftentimes break the default way of doing things.

Version control

Many commercial IDEs come with some half-baked attempt to implement version control. Recently, these version control systems have always unusable. Before, it was because in-house vcs never worked. Now, it's because adding a gui to git prevents users from fully utilizing the tool. Many of these IDEs do not allow users to easily change their git server to anything not owned by Microsoft. Using git over http? No thanks, we use the GitHub API. Lack of choice is also a major issue. Not every project uses git and not every user wants to use git.

In the terminal, a user can choose whichever version control is best suited for the job. Mercurial, Git, cvs, Subversion, Fossil, or even GNU Bazaar. There is no vendor lock-in when the user has choice.

As a ridiculous example, a user might want to use ZFS as a version control system. Allow me to demonstrate:

# initial 'clone'
$ ssh user@host "zfs send zroot/ROOT/repos/myproject" | zfs receive zroot/ROOT/repos/myproject

# make a 'commit'
$ zfs snapshot zroot/ROOT/repos/myproject@updateReadme

# push a 'commit'
$ zfs send zroot/ROOT/repos/myproject@updateReadme | ssh user@host "zfs receive -F zroot/ROOT/repos/myproject@updateReadme"

# pull a 'commit'
$ ssh user@host "zfs send zroot/ROOT/repos/myproject@updateReadme" | zfs receive -F zroot/ROOT/repos/myproject

The graphical IDE limits the user's choice of version control system greatly. A user's environment should not be so opinionated as to discourage users from exercising their right to make their own decisions.

Conclusion

The UNIX terminal is an integrated development environment. Every single component necessary for software development is present. Unnecessary anti-features are largely not present in the UNIX terminal. If human brains think in language, why avoid learning a computing interface that allows language based interaction?

Assembling a 'custom' development environment is not a difficult task. Learning how to click buttons is a waste of time. Becoming dependent on autocomplete is lazy. Refusal to read man pages is the way of Microsoft cattle. The UNIX philosophy has worked reliably for nearly 50 years without much change. UNIX is the only type of environment that is sustainable, maintainable, and dependable. Choose freedom, choose the UNIX 'IDE'.

Objections

Cope harder. Your IDE is shit. You will never be the UNIXMENSCH.