Abbreviations: Mother Ship

<<<<<<< HEAD

Table of Contents

This tangle is for extra configurations that are meant for PCs with a GUI that a user interacts with directly (as opposed to a server) and it has stuff that aren't going to be used on servers.

I'm putting it in dingehaufen/conf.d/ so it should be linked to in .config/fish/conf.d/ for PCs that need it.

Mount Drives

This is an abbreviation that mounts both the cryfs folders and the external (LUKs) drive.

abbr --add -- md "mountcryfs; mount-data"

Function: Mount Data

This is a function to mount one of the external encrypted USB drives that I use. It makes a lot of assumptions about names so it's pretty much an alias or shortcut, but sometimes things change so I added a little bit of flexibility to it and will try to document it enough that I can figure out what it's doing if I need to change (or fix) it.

The Function

This is the function declaration. There's going to be three optional arguments that it might take.

Argument Default Description
device sdb1 Name of the device as shown by fdisk -l without the directory (/dev/)
name monkeymount Name to use when opening the device
folder irvin Place to mount the contents of the disk (without /media/ at the beginning).

So if I plug in the USB drive and it shows up at /dev/sda1 and I decide that the mapped name will be "umma" and the folder will be "gumma". Then I

function mount-data --argument-names device name folder --description "Mount an encrypted drive."
    set ERROR 1

The ERROR is a number to return in the event we bail on mounting the drive for some reason.

The Parts

The Device

This is the name of the device in /dev that represents the drive to mount.

This command is useful sometimes. More so after it's been mounted.

lsblk -e7

This one is generally useful if you know the model of the drive.

sudo fdisk -l | grep sd -A 1

Note to future self: Consider making this an environment variable so you don't have to edit it if you switch USB ports.

if test -z $device
    set device "sdb1"
end

We'll add the /dev to it (without checking that it's already there for now) and then make sure it's a valid block-device.

set DEVICE_PATH "/dev/$device"

if not test -b $DEVICE_PATH
    echo "'$DEVICE_PATH' is not a valid block-device"
    mount-data-help
    return $ERROR
end

To be nice we'll let the user know what we're using.

echo "Using Device: $DEVICE_PATH"

The Mapping Name

This is the name that will be put into /dev/mapper/ which mount will use to mount the drive.

if test -z $name
    set name "monkeymount"
end
echo "Device Mapping: $name"

Mount Path

Now we'll handle the folder where the drive will be mounted. If the user doesn't give one the default is "irvin".

if test -z $folder
    set folder "irvin"
end

We'll assume that the folder is going inside the /media/ folder and that only the final folder (or path below /media/) is being passed in.

set MOUNT_PATH "/media/$folder"

If there's already something in the folder then we won't try and mount it.

if set COUNT (count (ls $MOUNT_PATH/))
    echo "$MOUNT_PATH not empty, not mounting"
    return $ERROR
end

If the folder doesn't exist we'll create it.

if not test -d $MOUNT_PATH
    echo "Creating '$MOUNT_PATH'"
    sudo mkdir --parents $MOUNT_PATH
end
echo "Mounting at: $MOUNT_PATH"

Mounting the Drive

First we'll use cryptsetup to decrypt the drive and put the mapping into /dev/mapper/.

echo
echo "Mounting External Data Drive"

sudo cryptsetup open $DEVICE_PATH $name

Now we'll mount the device to a folder.

sudo mount /dev/mapper/$name $MOUNT_PATH

A Help Printer

This is just a function to print a help string.

function mount-data-help
    echo "Mount an attached encrypted drive."
    echo
    echo "Usage: mount-data [device [name [folder]]]"
    echo "    device: /dev/<device block file>"
    echo "    name: /dev/wrapper/<name> to use"
    echo "    folder: /media/<folder> to mount into"
end

Links

Cerberus User Paths

Table of Contents

This is a configuration to add to the fish PATH. The current version of fish uses a special command called fish_add_path when you want to add locations to the user path. If you just naively append to the PATH in the config file then fish will keep adding to the PATH every time you log in so the fish_add_path prevents adding paths that are already stored in the environment variable. Unfortunately the raspberry PI I'm using has Debian 11 which has fish version 3.1.2 which predates the fish_add_path command so I'll have to add to the path the old fashioned way.

The additions will be in dingehaufen/conf.d/extra_paths.fish which has to be then linked or copied into /.config/fish/conf.d/.

contains $HOME/bin $fish_user_paths; or set --universal --append fish_user_paths $HOME/bin
contains $HOME/.local/bin $fish_user_paths; or set --universal --append fish_user_paths $HOME/.local/bin

Links

Emacs init.el

This is an emacs configuration file. I had this in another repository and have been adding to it over the decades, occasionally removing things when troubleshooting but otherwise it's just a jumble right now, so I'm putting it in the fish-based repository to work on it.

The tangle creates a file give-the-fish/dingehaufen/init.el that you should copy or link into the right place ~/.emacs.d right now.

At some post I should look into breaking up the configuration (see https://emacs.stackexchange.com/a/18441 for an example).

Tangle Source

<<package-management>>

<<activate-pyvenv>>

<<org-mode>>

;; make sure org-babel comes before jupyter or any other code-based settings
<<org-babel>>

<<org-export-python>>

<<emacs-settings>>

<<emacs-file-locks>>

<<toggle-input-method>>

;; <<python-elpy>>

(custom-set-variables
       ;; custom-set-variables was added by Custom.
       ;; If you edit it by hand, you could mess it up, so be careful.
       ;; Your init file should contain only one such instance.
       ;; If there is more than one, they won't work right.
       '(js-indent-level 2)
       '(js2-basic-offset 2)
       '(js2-bounce-indent-p t)
       '(org-export-backends '(ascii html icalendar latex org))
       '(package-selected-packages
         (quote
          (htmlize ox-nikola ox-rst web-mode swiper smex paredit magit jedi ido-ubiquitous idle-highlight-mode god-mode fuzzy feature-mode csv-mode autopair ac-js2))))

      (custom-set-faces
       ;; custom-set-faces was added by Custom.
       ;; If you edit it by hand, you could mess it up, so be careful.
       ;; Your init file should contain only one such instance.
       ;; If there is more than one, they won't work right.
       '(rst-level-1 ((t (:background "white" :foreground "royal blue"))))
       '(rst-level-2 ((t (:background "white"))))
       '(rst-level-3 ((t (:background "cyan"))))
       '(rst-level-4 ((t (:background "magenta")))))

      ;; rst minor-mode
      (defun turn-on-rst () (rst-minor-mode 1))
      (add-hook 'python-mode-hook 'turn-on-rst)

      ;; hide-show mode
      (defun turn-on-hideshow () (hs-minor-mode 1))
      (add-hook 'python-mode-hook 'turn-on-hideshow)

      ;; make no-tabs universal
      (setq-default indent-tabs-mode nil)

      ;; ipython shell
      (setq python-shell-interpreter "ipython"
            python-shell-interpreter-args "-i")

      <<web-mode>>

      <<auto-complete>>

      (define-global-minor-mode select-electric-pair-mode electric-pair-mode
        (lambda ()
          (when (not (memq major-mode
                           (list 'web-mode 'js2-mode)))
            (electric-pair-mode))))

      (select-electric-pair-mode 1)

      ;; magit
      (setq global-magit-file-mode 1)

      ;; setup the keybinding to launch magit
      (global-set-key (kbd "C-x g") 'magit-status)

      <<tramp-mode>>

      <<tramp-backups>>

<<god-mode>>

<<jupyter-emacs>>

<<general-text>>

<<javascript>>

<<feature-mode>>

<<emacs-gui>>

<<yaml>>

;; <<vue>>

;; <<bats>>

<<backups>>

<<no-sudo-backups>>

;; <<markdown-mode>>

<<dockerfile-mode>>

<<keychain>>

<<hideshow-org>>

;; <<flycheck-mypy>>

<<add-path>>

Package Management

;; emacs package management
(require 'package)

;; add the repositories
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t)

;; refresh the list
(when (not package-archive-contents)
  (package-refresh-contents))

(require 'use-package)

Pyvenv

To prevent errors when emacs starts up and tries to load jupyter (for emacs-jupyter) we need jupyter to be on the path. Now that debian and ubuntu don't want you to install python packages globally we need another way. I had installed it with pipx, which does work, but pipx doesn't doesn't install standalone libraries and sometimes breaks when trying to install dependencies so I think for this case it's better to avoid it and instead use a virtual-environment. Since it has to be activated before anything else that uses python packages, activating the environment should be put fairly early on in the init.el file.

(require 'pyvenv)
(pyvenv-activate "~/.virtualenvs/emacs-environment/")

This assumes that there's a virtual-environment named emacs-environment setup (with jupyter at least). Note that you could load elpy instead of just pyvenv by itself, but elpy is giving me errors (or at least lots of warnings) when it loads and I don't feel like troubleshooting it right now, since it doesn't play well with org-mode anyway.

Emacs Settings

;; show column-numbers
(column-number-mode)

;; show matching parentheses
(show-paren-mode 1)
(setq show-paren-delay 0)

;; global parentheses matching (`autopair` package needs to be installed)
(electric-pair-mode 1)

;; turn off auto-fill mode
(remove-hook 'text-mode-hook #'turn-on-auto-fill)

;; hide menu-bar by default
(menu-bar-mode -1)

;; hide the toolbar
(tool-bar-mode -1)

;; disable the scrollbar
(toggle-scroll-bar -1)

(add-to-list 'default-frame-alist '(background-color . "white"))
(add-to-list 'default-frame-alist '(foreground-color . "black"))

;; dark slate blue
;; (add-to-list 'default-frame-alist '(cursor-color . "#483D8B"))
;; dark red
(add-to-list 'default-frame-alist '(cursor-color . "#8B0000"))

;; Disable Bell
(setq ring-bell-function 'ignore)

File Locks

A lock got corrupted once in the cryfs directory, making the editing file unreadable. You can fix it by copying everything but the corrupted file out, destroying and re-creating the cryfs mount and copying the files back in, but hopefully this will fix it. It does mean that two people could edit the same file and cause problems, but oh, well.

(setq create-lockfiles nil)

Toggle Input Mode

This allows you to switch to latex input and then back using C-\. This is useful to embed special characters. Although you could probably just do the same thing with math mode if you want to wait until exporting.

;; (setq default-input-method "TeX")
(setq default-input-method "TeX")

Tramp Mode

Use SSH

;; tramp mode
(setq tramp-default-method "ssh")

No Backups

This is from the emacs manual.

Turn Off For Tramp Only

The configuration is currently saving backups to a local directory, so when I use tramp I get warnings about it. It doesn't tell you why but according to the emacs wiki this is a potential security leak (although probably not in the way I'm using it). Anyway, I've never used the backups so I'll just disable them for tramp.

;; disable tramp-backups
(add-to-list 'backup-directory-alist
             (cons tramp-file-name-regexp nil))

Note: This turns out to solve the wrong problem so I added another rule in the next section.

Turn Off For Sudo

Turning off the backups for tramp only fixed one case, but it turned out that the thing that made me look into this was using sudo on my local machine to opne the /etc/hosts file so I was actually solving the wrong (or only part of the) problem. This next bit is supposed to turn off all backups where you use sudo. So it probably doesn't belong under tramp any more. Maybe I'll move it later

(setq backup-enable-predicate
      (lambda (name)
        (and (normal-backup-enable-predicate name)
             (not
              (let ((method (file-remote-p name 'method)))
                (when (stringp method)
                  (member method '("su" "sudo"))))))))

God Mode

;; god-mode
(require 'god-mode)
(global-set-key (kbd "<escape>") 'god-mode-all)
(global-set-key (kbd "C-$") 'god-mode-all)
(global-set-key (kbd "<Scroll_Lock>") 'god-mode-all)
(define-key god-local-mode-map (kbd ".") 'repeat)

(setq god-exempt-major-modes nil)
(setq god-exempt-predicates nil)

(defun my-update-cursor ()
  (setq cursor-type (if (or god-local-mode buffer-read-only)
                        'box
                      'bar)))
(defun c/god-mode-update-cursor ()
  (let ((limited-colors-p (> 257 (length (defined-colors)))))
    (cond (god-local-mode (progn
                            (set-face-background 'mode-line (if limited-colors-p "white" "#e9e2cb"))
                            (set-face-background 'mode-line-inactive (if limited-colors-p "white" "#e9e2cb"))))
          (t (progn
               (set-face-background 'mode-line (if limited-colors-p "black" "#0a2832"))
               (set-face-background 'mode-line-inactive (if limited-colors-p "black" "#0a2832")))))))

(add-hook 'god-mode-enabled-hook 'my-update-cursor)
(add-hook 'god-mode-disabled-hook 'my-update-cursor)

;; window bindings for god-mode
(global-set-key (kbd "C-x C-o") 'other-window)
(global-set-key (kbd "C-x C-1") 'delete-other-windows)
(global-set-key (kbd "C-x C-2") 'split-window-below)
(global-set-key (kbd "C-x C-3") 'split-window-right)
(global-set-key (kbd "C-x C-0") 'delete-window)
(global-set-key (kbd "C-x C-B") 'switch-to-buffer)

;; allow using 's' and 'r' for repeated searches
(require 'god-mode-isearch)
(define-key isearch-mode-map (kbd "<escape>") 'god-mode-isearch-activate)
(define-key god-mode-isearch-map (kbd "<escape>") 'god-mode-isearch-disable)

(define-key god-local-mode-map (kbd ".") 'repeat)
;; set a default virtual environment
(pyvenv-activate "~/.virtualenvs/emacs")

;; hide-show is broken by god mode.
;; this adds universal quick and dirty code-folding that works
(defvar hs-special-modes-alist
  (mapcar 'purecopy
          '((c-mode "{" "}" "/[*/]" nil nil)
            (c++-mode "{" "}" "/[*/]" nil nil)
            (bibtex-mode ("@\\S(*\\(\\s(\\)" 1))
            (java-mode "{" "}" "/[*/]" nil nil)
            (js2-mode "{" "}" "/[*/]" nil))))

(defun toggle-selective-display (column)
  (interactive "P")
  (set-selective-display
   (or column
       (unless selective-display
         (1+ (current-column))))))

(defun toggle-hiding (column)
  (interactive "P")
  (if hs-minor-mode
      (if (condition-case nil
              (hs-toggle-hiding)
            (error t))
          (hs-show-all))
    (toggle-selective-display column)))
(load-library "hideshow")
(global-set-key (kbd "C-+") 'toggle-hiding)
(global-set-key (kbd "C-|") 'toggle-selective-display)
(add-hook 'java-mode-hook       'hs-minor-mode)
(add-hook 'sh-mode-hook         'hs-minor-mode)
(add-hook 'js2-mode-hook         'hs-minor-mode)

Python and elpy

  ;; elpy
(use-package elpy
  :ensure t
  :defer t
  :init
  (advice-add 'python-mode :before 'elpy-enable))
  (add-to-list 'auto-mode-alist '("\\.py" . python-mode))

Emacs Jupyter

(org-babel-jupyter-override-src-block "python")

Fish

;; fish functions
'(sh-basic-offset 2)
'(sh-indentation 2)
(setq auto-mode-alist (cons '("\\.fish$" . shell-script-mode) auto-mode-alist))

Org-mode

  ;; org-mode
  (require 'org)
  (define-key global-map "\C-cl" 'org-store-link)
  (define-key global-map "\C-ca" 'org-agenda)
  (setq org-log-done t)

  ;; org-mode agendas
  (setq org-agenda-files (list "~/documents/roku-chiji/repository/kanban.org"))

  ;; org-capture
  (setq org-default-notes-file (concat "~/documents/roku-chiji/repository/" "bugs.org"))
  (define-key global-map "\C-cc" 'org-capture)

  (setq org-capture-templates
        '(("b" "Bug" entry (file+headline "~/documents/roku-chiji/repository/bugs.org" "Bugs")
           "* BUG %?\n  %i\n  %a")))

  ;; todo-state names
  (setq org-todo-keywords
          '((sequence "TOMORROW" "TODAY" "DOING" "|" "DONE")))

  ;; org clean-outlines

  (setq org-startup-indented t
        org-hide-leading-stars t
        org-indent-indentation-per-level 1)

  ;; word-wrap
  (global-visual-line-mode 1)

  ;; start the calendar on monday
  (setq calendar-week-start-day 1)

  ;; start with outline folded
  (setq org-startup-folded t)

org-export python mode

This just stops emitting the message that emacs is using a default 4 spaces when exporting python.

(setq python-indent-guess-indent-offset t)  
(setq python-indent-guess-indent-offset-verbose nil)

web-mode

  ;; web-mode
  (require 'web-mode)
  (add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))
  (add-to-list 'auto-mode-alist '("\\.tmpl\\'" . web-mode))
  (add-to-list 'auto-mode-alist '("\\.phtml\\'" . web-mode))
  (add-to-list 'auto-mode-alist '("\\.tpl\\.php\\'" . web-mode))
  (add-to-list 'auto-mode-alist '("\\.[agj]sp\\'" . web-mode))
  (add-to-list 'auto-mode-alist '("\\.as[cp]x\\'" . web-mode))
  (add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode))
  (add-to-list 'auto-mode-alist '("\\.mustache\\'" . web-mode))
  (add-to-list 'auto-mode-alist '("\\.djhtml\\'" . web-mode))

  (defun my-web-mode-hook ()
    "Hooks for Web mode."
    (setq web-mode-markup-indent-offset 2)
    (setq web-mode-css-indent-offset 2)
    (setq web-mode-code-indent-offset 2)
    (setq web-mode-enable-current-column-highlight t)
    (setq web-mode-enable-current-element-highlight t)
    (setq web-mode-engines-alist
        '(("jinja"    . "\\.html\\'"))
        )
  )
  (add-hook 'web-mode-hook  'my-web-mode-hook)

auto-complete

  ;; auto-complete
  ;; (defun turn-on-autocomplete () (auto-complete-mode 1))
  (add-to-list 'load-path "~/.emacs.d/lisp")
  (require 'auto-complete-config)
  (add-to-list 'ac-dictionary-directories "~/.emacs.d/ac-dict")
  (ac-config-default)
  (defadvice auto-complete-mode (around disable-auto-complete-for-python)
  (unless (eq major-mode 'python-mode) ad-do-it))

general text

;; increase/decrease text size
(global-set-key (kbd "C-c C-+") 'text-scale-increase)
(global-set-key (kbd "C--") 'text-scale-decrease)

javascript

;; js2
(add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))

org-babel

  ;; org-babel
(require 'ob-js)

  (add-to-list 'org-src-lang-modes '("rst" . "rst"))
  (add-to-list 'org-src-lang-modes '("feature" . "feature"))
  (add-to-list 'org-src-lang-modes '("org" . "org"))
  (add-to-list 'org-src-lang-modes '("css" . "css"))
  (add-to-list 'org-src-lang-modes '("plantuml" . "plantuml"))
  (add-to-list 'org-src-lang-modes '("conf" . "conf"))

  (org-babel-do-load-languages
   'org-babel-load-languages
   '(
     (plantuml . t)
     (shell . t)
     (emacs-lisp . t)
     (latex . t)
     (org . t)
     (js . t)
     (jupyter . t)
     ))

  (setq org-plantuml-jar-path (expand-file-name "/usr/share/java/plantuml.jar"))

  ;; Don't treat underscores as sub-script notation
  (setq org-export-with-sub-superscripts nil)

  ;; Don't re-evaluate the source blocks before exporting
  (setq org-export-babel-evaluate nil)

  ;; don't confirm block evaluation
  (setq org-confirm-babel-evaluate nil)

  ;;; display/update images in the buffer after evaluation
  (add-hook 'org-babel-after-execute-hook 'org-display-inline-images 'append)

  ;; noweb expansion only when you tangle
  (setq org-babel-default-header-args
        (cons '(:noweb . "tangle")
              (assq-delete-all :noweb org-babel-default-header-args))
        )

  ;; syntax highlighting in org-files
  (setq org-src-fontify-natively t)

  ;; export org to rst
  (require 'ox-rst)

  ;; export org to nikola
  (require 'ox-nikola)

  ;; export to latex/pdf
  (require 'ox-latex)

  ;; syntax-highlighting for pdf's
  (add-to-list 'org-latex-packages-alist '("" "minted"))
  (setq org-latex-listings 'minted)
  (setq org-latex-pdf-process '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))

  ;; let the user set the indentation so you can insert text between methods in classes.
  (setq org-src-preserve-indentation t)

  ;; pygmentize ipython
  (add-to-list 'org-latex-minted-langs '(ipython "python"))

Feature Mode

(add-to-list 'auto-mode-alist '("\\.feature" . feature-mode))

yaml

(add-hook 'yaml-mode-hook
          (lambda ()
            (define-key yaml-mode-map "\C-m" 'newline-and-indent)))

Vue.js

;; setup files ending in “.vue” to open in vue-mode
;; (add-to-list 'auto-mode-alist '("\\.vue\\'" . vue-mode))

Bats

The Bash Automated Test System mode.

Keybinding Description State
C-c C-a Run all bat-files in the current directory Works
C-c C-, Run all the tests in the current buffer Works
C-c M-, Run the test where the cursor is Doesn't Work

There's a ticket on github to add this feature (?) to bats, but the old developers stopped supporting it and I don't know if the fork has it yet. It isn't working if you install bats from Ubuntu's repositories as of Bionic Beaver.

(add-to-list 'auto-mode-alist '("\\.bat\\'" . bats-mode))

Backups

From the Emacs Wiki.

(setq backup-directory-alist 
      '(("." . "/tmp/")))
(setq auto-save-file-name-transforms
      `((".*" , "/tmp/" t)))

Markdown Mode

(use-package markdown-mode
 :ensure t
 :mode (("README\\.md\\'" . gfm-mode)
         ("\\.md\\'" . markdown-mode)
         ("\\.markdown\\'" . markdown-mode))
 :init (setq markdown-command "pandoc")
)

Dockerfile Mode

(require 'dockerfile-mode)
(add-to-list 'auto-mode-alist '("Dockerfile\\'" . dockerfile-mode))

Flycheck

;; flycheck
(use-package flycheck
  :ensure t
  :config
  (global-flycheck-mode t)
  ;; note that these bindings are optional
  (global-set-key (kbd "C-c n") 'flycheck-next-error)
  ;; this might override a default binding for running a python process,
  ;; see comments below this answer
  (global-set-key (kbd "C-c p") 'flycheck-prev-error)
  )
;; flycheck-pycheckers
;; Allows multiple syntax checkers to run in parallel on Python code
;; Ideal use-case: pyflakes for syntax combined with mypy for typing
(use-package flycheck-pycheckers
  :after flycheck
  :ensure t
  :init
  (with-eval-after-load 'flycheck
    (add-hook 'flycheck-mode-hook #'flycheck-pycheckers-setup)
    )
  (setq flycheck-pycheckers-checkers
    '(
      mypy3
      pyflakes
      )
    )
  )
;; elpy
(use-package elpy
  :after poetry
  :ensure t
  :config
  (elpy-enable)
  (add-hook 'elpy-mode-hook 'poetry-tracking-mode) ;; optional if you're using Poetry
  (setq elpy-rpc-virtualenv-path 'current)
  (setq elpy-syntax-check-command "~/.virtualenvs/neurotic-networks/bin/pyflakes") ;; or replace with the path to your pyflakes binary
  ;; allows Elpy to see virtualenv
  (add-hook 'elpy-mode-hook
        ;; pyvenv-mode
        '(lambda ()
           (pyvenv-mode +1)
           )
        )
  ;; use flycheck instead of flymake
  (when (load "flycheck" t t)
  (setq elpy-modules (delq 'elpy-module-flymake elpy-modules))
  (add-hook 'elpy-mode-hook 'flycheck-mode))
  )
;; poetry
(use-package poetry
  :ensure t)

Keychain

This is to be able to use ssh-agent (via keychain).

  • `keychain` needs to be installed (e.g. via apt)
  • It needs to be running - Add this to the fish.config
if status --is-interactive
 keychain --eval --quiet -Q id_rsa | source
end
(require 'keychain-environment)
(keychain-refresh-environment)

Hideshow-Org

(add-to-list 'load-path "~/projects/third-party/hideshow-org/")
(require 'hideshow-org)

Convert a Document To PDF With Pandoc

What's This About?

This is a function to help convert documents to PDF using pandoc. I was motivated to do this because the EPUB readers I tried (on Ubuntu) don't seem to do a good job of styling the text or providing the options to really let you do it (at least not easily through the GUI). Foliate seems to be the best for styling, but I occasionally run into EPUB files that it won't open so I thought it'd be useful to convert them to PDF sometimes.

Pandoc will convert an ePub or other formatted file to PDF (using pdflatex) without much configuration

pandoc inputfile.epub -o output.pdf

but it defaults to using Computer Modern, making it look like those old Springer books in the library, so I thought I'd create this function to document how to change the font in case I forget later on.

Headers

You can set the font as a command line argument to pandoc (e.g. -V fontfamily:libertine ) but I thought it'd be better to create a tex header snippet so that I could add more configurations if I needed to.

The function is going to assume that the pagella snippet is in a folder in ~/.config/fish/extras/ which I created using a symlink to the extras folder in this repository, but it'll also take a path to the header if it's given.

Libertinus

This is a font I ran into while searching around for instructions on changing the pandoc font. I'm not convinced it's better than Palatino, but it's better than Computer Modern, anyway.

\usepackage{libertinus}
\usepackage[T1]{fontenc}
\usepackage{sectsty}
\sectionfont{\clearpage}

Pagella

The Libertine/Libertinus font wasn't really what I was looking for so I made Tex Gyre Pagella version as well.

\usepackage{tgpagella}
\usepackage[T1]{fontenc}
\usepackage{sectsty}
\sectionfont{\clearpage}

Note: I originally accidentally put pagella and not tgpagella which took me a while to trouble-shoot, so for the future remember - it's "Tex Gyre Pagella" not just "Pagella". Also it's sectsty not secsty.

The Function

Nothing fancy here, it just adds the extra header file. I originally added the --table-of-contents flag but it creates one from the EPUB anyway so that caused it to have two tables of contents.

function doc2pdf -d "Convert document to pdf with pandoc" --argument-names SOURCE HEADER
    set TARGET $(path change-extension pdf $SOURCE)

    if test -z $HEADER
        set HEADER ~/.config/fish/extras/pagella.tex
    end

    pandoc --standalone $SOURCE --output $TARGET --include-in-header $HEADER
end

Links

Dim Monitor

function dim_monitor -d "Set monitor brightness" \
    --argument-names OUTPUT BRIGHTNESS

  # -z : test for empty string
  if test -z $BRIGHTNESS
    set BRIGHTNESS 0
  end

  if test -z $OUTPUT
      echo "You must pass in the 'output' e.g. 'DVI-D-0'"
      echo "Usage: dim_monitor OUTPUT BRIGHTNESS"
   else
       xrandr --output $OUTPUT --brightness $BRIGHTNESS --auto
   end
end

Dim Left Monitor

function dimleftmonitor -d "Set HDMI-0 brightness" \
    --argument-names BRIGHTNESS OUTPUT

  # -z : test for zero (empty) string

  if test -z $OUTPUT
      set OUTPUT "HDMI-0"
  end

  if test -z $BRIGHTNESS
      set BRIGHTNESS 0
  end

  # xrandr --output $OUTPUT --brightness $BRIGHTNESS --auto
  dim_monitor $OUTPUT $BRIGHTNESS
end
function undimleftmonitor -d "Undim the Left Monitor" \
    --argument-names OUTPUT

      if test -z $OUTPUT
          set OUTPUT "HDMI-0"
      end

      dimleftmonitor 1 $OUTPUT
end

Git Checkout File Function

Declaring the Function

This is an alias function to checkout a file or folder from another branch, mostly as a place to document it since I keep forgetting the syntax.

function gitmefile -d "Checkout folder or file from another branch" \
    --argument-names BRANCH PATH_TO_FILE

I originally called PATH_TO_FILE but that of course clobbered the PATH variable and all of a sudden it couldn't find git.

Checkout the File

This is the git command, nothing fancy, although trying to read the documentation didn't make it obvious to me that this is what you should do.

git checkout $BRANCH -- $PATH_TO_FILE

Check If It Succeeded

The git error message when you pass it an unknown branch is fatal: invalid reference: <branch> which, in context is relatively easy to figure out, but is a little obscure at first glance, so I'll add an extra message in case there is an error.

if test $status -ne 0
    echo "There was a git error using your arguments: branch='$BRANCH' path='$PATH_TO_FILE'."

    string match --regex --quiet "(?<matched>$BRANCH)" (git branch)
    if test -z $matched
        echo "No branch matches '$BRANCH'."
    end
end

The option given to string match tell fish to use regular expressions instead of the default glob-type expressions and to not echo any matches it finds to the screen. The arguments to test don't have long-versions so I'll put them in a table to make it clearer.

Option Meaning
-ne Not equal to
-z It is a zero (empty) string

References

Function: Apt Search

This function pipes the output of apt search to less, preserving the colors. apt doesn't have an option to preserve color when the output is piped so the function uses unbuffer which disables the stripping of the color. unbuffer is part of the expect package. On Ubuntu Lunar Lobster it doesn't come installed by default so you have to install expects to get unbuffer.

sudo apt install expects
function aptsearch -d "Paging apt search" --argument-names keyword
    unbuffer apt search $keyword | less -R
end

Links

SSH Agent Config Fragment

SSH Agent

This is the fragment to make sure the ssh-agent is running when you open the terminal.

Put this in ~/.config/fish/conf.d/.

if status --is-interactive
    keychain --eval --quiet --quick id_rsa | source
end

The documentation for the status comand says that is-interactive is actually a sub-command (not an option, although I'm calling it like it is one) and that it:

Returns 0 if fish is interactive - that is, connected to a keyboard.

Which is an oddly unintuitive description. I think it means that it won't pass the conditional if I try to run the fragment as a function… I can't remember why I used it, exactly ,but I think it's something you need if you want it to be loaded when you login.

Although the name keychain makes it sound like it's a general password manager, according to the man-page it's meant specifically to manage the ssh-agent. It will check if you already have an ssh-agent running and only start one if you don't. This way you don't end up starting one for every screen you open up.

The --eval option sends the SSH-Agent message to stdout, --quiet suppresses other messages, --quick tells it to use a running ssh-agent if it finds one without verifying the keys and then we pipe it to source to load the environment.

Links