#+TITLE: Shell #+AUTHOR: Christopher James Hayward #+EMAIL: chris@chrishayward.xyz #+PROPERTY: header-args:emacs-lisp :tangle shell.el :comments org #+PROPERTY: header-args :results silent :eval no-export :comments org #+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil #+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil Shell environment integration. * Setup :PROPERTIES: :header-args: :tangle ../config/profile :comments org :END: Override the default behaviour of the Shell environment to integrate with Emacs. ** Force colours When using Emacs on the TTY, the colours sometimes will default to 16 or 8 colours, making it look horrible. It's possible to override this behaviour on every platform by manually set the terminal type to =xterm-256color=. #+begin_src shell export TERM=xterm-256color #+end_src ** Setting up the $PATH Ensure =~/.local/bin= has been added to the ~$PATH~ environment variable, this location is used frequently to deploy local binaries. #+begin_src shell export PATH=$PATH:~/.local/bin #+end_src ** Starting Emacs by default on TTY1 When launching into a new session on TTY1, if the display server is not running, run ~startx~[fn:1]. This will launch the window manager. #+begin_src shell if [ -z "${DISPLAY}" ] && [ "${XDG_VTNR}" -eq 1 ]; then exec startx fi #+end_src ** Creating symbolic links The system looks for the default shell profile under ~bash~[fn:2] at =~/.profile=. Creating a symbolic link from this location to our configuration will override the startup behaviour. #+begin_src emacs-lisp (dotfiles/symlink "~/.emacs.d/config/profile" "~/.profile") #+end_src * Methods Define methods for interaction between Emacs and the underlying shell environment. ** Run an external process Define a method to run an external process, launching any application on a new process without interferring with Emacs. #+begin_src emacs-lisp (defun dotfiles/run (cmd) "Run an external process." (interactive (list (read-shell-command "λ "))) (start-process-shell-command cmd nil cmd)) #+end_src ** Apply command to call process Define a method to apply commands to the current call process, this is to avoid issues with hooks but can impact the performance of Emacs. #+begin_src emacs-lisp (defun dotfiles/run-in-background (cmd) (let ((command-parts (split-string cmd "[ ]+"))) (apply #'call-process `(,(car command-parts) nil 0 nil ,@(cdr command-parts))))) #+end_src * Shortcuts Place keybindings for executing shell commands behind =SPC x=: + Run shell commands with =x= + Run async shell commands with =z= #+begin_src emacs-lisp (dotfiles/leader "x" '(:ignore t :which-key "Run") "xx" '(dotfiles/run :which-key "Run") "xz" '(async-shell-command :which-key "Async")) #+end_src * Footnotes [fn:1] https://x.org [fn:2] https://gnu.org/software/bash/