Skip to content

Instantly share code, notes, and snippets.

@Kyrremann
Last active December 26, 2024 22:07
Show Gist options
  • Save Kyrremann/24420c7ceee5f25a82d14255b7990766 to your computer and use it in GitHub Desktop.
Save Kyrremann/24420c7ceee5f25a82d14255b7990766 to your computer and use it in GitHub Desktop.
My dotfiles
echo ".bash_profile"
# Harden homebrew
# from: https://github.com/AtropineTears/TheMacHardeningScripts/blob/main/AutoHarden_MacOSX/scripts/brew/brew-harden.sh
export HOMEBREW_NO_INSECURE_REDIRECT=1
export HOMEBREW_FORCE_BREWED_CURL=1
export HOMEBREW_AUTO_UPDATE_SECS=60
export HOMEBREW_DISPLAY_INSTALL_TIMES=1
export HOMEBREW_NO_ANALYTICS=1
export HOMEBREW_AUTO_UPDATE_SECS=300
export HOMEBREW_CLEANUP_PERIODIC_FULL_DAYS=3
export GOPATH=/Users/kyrremann/workspace/go
export HISTCONTROL=ignoreboth
export EDITOR="emacsclient"
export LANG="en_US.UTF-8"
export PAGER=cat
export TERM=xterm-256color
export LESS="FRXim"
export PATH=/Users/kyrremann/.local/bin:/Applications/Emacs.app/Contents/MacOS:/Applications/Emacs.app/Contents/MacOS/bin:/Users/kyrremann/.krew/bin:$GOPATH/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
. '/usr/local/bin/google-cloud-sdk/path.bash.inc'
eval "$(/opt/homebrew/bin/brew shellenv)"
. /opt/homebrew/opt/asdf/libexec/asdf.sh
if [ -s ./.bashrc ]
then
source ./.bashrc
else
echo "No .bashrc found"
fi
. "$HOME/.cargo/env"
# The next line enables shell command completion for gcloud.
. '/usr/local/bin/google-cloud-sdk/completion.bash.inc'
export BASH_COMPLETION_COMPAT_DIR="$HOMEBREW_PREFIX/etc/bash_completion.d"
if [[ -d "$HOMEBREW_PREFIX/etc/bash_completion.d" ]]; then
for COMPLETION in "${HOMEBREW_PREFIX}/etc/bash_completion.d/"*
do
echo "Sourcing ${COMPLETION}"
# shellcheck source=/dev/null
[[ -r "${COMPLETION}" ]] && source "${COMPLETION}"
done
fi
# Set up gpg-agent automatically for every shell
if [ -z "$(pgrep gpg-agent)" ]; then
eval "$(gpg-agent --daemon)"
fi
ssh-add --apple-use-keychain 2>/dev/null;
# The "FRX" options make "less" more compatible with "git", and the "i" option enables case insensitive search in less.
export LESS="FRXim"
### ###
# Aliases #
### ###
alias ls='TERM=screen ls -GF'
alias ll='ls -alFh'
alias grep='grep --color=always --binary-files=without-match'
alias k=kubectl
complete -F _complete_alias k
alias kns=kubens
complete -F _complete_alias kns
alias ktx=kubectx
complete -F _complete_alias ktx
alias krew='k krew'
alias python=python3
### ###
# Functions #
### ###
cnrm() {
readonly cluster=${1:?"Cluster is missing"}; shift
readonly namespace=${1:?"Namespace is missing"}; shift
kubectl logs --context "$cluster" --namespace cnrm-system --container manager --tail=100 --follow=true \
"$(kubectl get pod --context "$cluster" --namespace cnrm-system --selector cnrm.cloud.google.com/scoped-namespace="$namespace" --no-headers -o jsonpath='{.items[0].metadata.name}')" "$@"
}
kube-all() {
readonly namespace=${1:?"Namespace is missing"}; shift
kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found --namespace="$namespace"
}
parse_git_branch() {
git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e "s/$(git rev-parse --abbrev-ref origin/HEAD 2> /dev/null | sed s/origin\\///)/~/" -e 's/* \(.*\)/[\1]/'
}
###
# Kube-ps1 (remove?)
###
source "/opt/homebrew/opt/kube-ps1/share/kube-ps1.sh"
export KUBE_PS1_SYMBOL_ENABLE=false
export KUBE_PS1_PREFIX="["
export KUBE_PS1_SUFFIX="]"
# export KUBE_PS1_SYMBOL_COLOR=''
# export KUBE_PS1_CTX_COLOR=''
# export KUBE_PS1_NS_COLOR=''
kubeoff
### ###
# PS1 #
### ###
# PROMPT_COMMAND='PS1_CMD1=$(git branch --show-current 2>/dev/null)'; PS1='[\t]\[\e[38;5;220m\][${PS1_CMD1}]\[\e[38;5;40m\]\W\[\e[0m\]\$ '
# https://bash-prompt-generator.org/
PROMPT_COMMAND='GIT_BRANCH=$(git branch --show-current 2>/dev/null)'
PS1='[\t]\[\e[1;33m\][${GIT_BRANCH}]\[\e[1;32m\]\W\[\e[0m\]\$ '
# export PS1='[\t]$(kube_ps1)\e[1;33m$(parse_git_branch)\e[0m\e[1;32m\W\e[0m\$ '
. "$HOME/.cargo/env"
(add-to-list 'package-archives
'("melpa" . "https://melpa.org/packages/") t)
(package-initialize)
(add-to-list 'default-frame-alist
'(fullscreen . maximized))
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package)
(package-install 'quelpa)
(package-install 'quelpa-use-package))
(require 'quelpa-use-package)
(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.
'(age-default-identity "~/.ssh/id_rsa" nil nil "Customized with use-package age")
'(age-default-recipient "~/.ssh/id_rsa.pub" nil nil "Customized with use-package age")
'(age-program "rage" nil nil "Customized with use-package age")
'(auth-sources
'(macos-keychain-internet macos-keychain-generic "~/.authinfo.gpg" "~/.netrc"))
'(auto-save-file-name-transforms '((".*" "~/.emacs.d/auto-save-list/" t)))
'(aw-keys '(97 115 100 102 103 104 106 107 108))
'(backup-by-copying t)
'(backup-directory-alist '(("." . "~/.emacs.d/backups")))
'(c-basic-offset 4)
'(clean-buffer-list-delay-general 1)
'(column-number-mode t)
'(comint-input-ignoredups t)
'(comint-input-ring-size 5000)
'(comint-mode-hook nil)
'(comint-process-echoes t)
'(comint-use-prompt-regexp t)
'(company-keywords-ignore-case t)
'(compilation-scroll-output t)
'(css-indent-offset 2)
'(custom-enabled-themes '(modus-vivendi))
'(custom-safe-themes
'("763bf89898a06b03f7b65fbc29857a1c292e4350246093702fdbd6c4e46e2cf0" "c71fd8fbda070ff5462e052d8be87423e50d0f437fbc359a5c732f4a4c535c43" "24168c7e083ca0bbc87c68d3139ef39f072488703dcdd82343b8cab71c0f62a7" "fb83a50c80de36f23aea5919e50e1bccd565ca5bb646af95729dc8c5f926cbf3" "e3a1b1fb50e3908e80514de38acbac74be2eb2777fc896e44b54ce44308e5330" "b6269b0356ed8d9ed55b0dcea10b4e13227b89fd2af4452eee19ac88297b0f99" "b02eae4d22362a941751f690032ea30c7c78d8ca8a1212fdae9eecad28a3587f" "c8b83e7692e77f3e2e46c08177b673da6e41b307805cd1982da9e2ea2e90e6d7" "78e6be576f4a526d212d5f9a8798e5706990216e9be10174e3f3b015b8662e27" "d9646b131c4aa37f01f909fbdd5a9099389518eb68f25277ed19ba99adeb7279" default))
'(delete-old-versions -1)
'(desktop-save-mode nil)
'(display-buffer-alist nil)
'(display-time-24hr-format t)
'(display-time-default-load-average nil)
'(display-time-mode t)
'(electric-pair-mode nil)
'(enable-recursive-minibuffers t)
'(frame-background-mode 'dark)
'(global-auto-revert-mode t)
'(global-diff-hl-mode t)
'(global-undo-tree-mode t)
'(go-ts-mode-indent-offset 4)
'(gud-dlv-command-name "/opt/homebrew/bin/dlv")
'(history-delete-duplicates t)
'(history-length 1000)
'(indent-tabs-mode t)
'(inhibit-startup-screen t)
'(ivy-count-format "(%d/%d) ")
'(ivy-use-selectable-prompt t)
'(ivy-use-virtual-buffers t)
'(js-indent-level 2)
'(kill-do-not-save-duplicates t)
'(kill-ring-max 1000)
'(kubel-use-namespace-list 'on)
'(line-number-mode nil)
'(lsp-pylsp-plugins-autopep8-enabled t)
'(lsp-pylsp-plugins-black-enabled t)
'(lsp-pylsp-plugins-jedi-completion-fuzzy t)
'(lsp-pylsp-plugins-pycodestyle-enabled t)
'(lsp-pylsp-plugins-rope-autoimport-enabled t)
'(lsp-yaml-bracket-spacing nil)
'(lsp-yaml-single-quote nil)
'(magit-diff-refine-hunk 'all)
'(magit-diff-refine-ignore-whitespace t)
'(magit-todos-exclude-globs '(".git/" "index.js.map"))
'(markdown-command "pandoc")
'(midnight-delay "23:00")
'(ns-right-alternate-modifier nil)
'(package-selected-packages
'(multiple-cursors mistty expand-region verb earthfile-mode bash-completion nginx-mode kotlin-mode inf-ruby copilot-chat quelpa-use-package yasnippet-snippets coterm all-the-icons-ivy exec-path-from-shell move-text magit-file-icons magit-section all-the-icons-ivy-rich counsel all-the-icons terraform-mode yasnippet yaml treepy pyvenv py-autopep8 pcre2el monokai-theme magit-todos link-hint highlight-indentation go-mode go ghub forge emacsql elpy diff-hl closql async magit dockerfile-mode marginalia kubel which-key dired-single flycheck-hl-todo rainbow-delimiters-mode markdown rubocopfmt enh-ruby-mode lin kotlin-ts-mode groovy-mode cargo-mode flycheck-rust terraform-doc rust-mode breadcrumb treesit-auto eglot emojify rainbow-mode toml company-lua flymake-lua lua-mode gotest pytest company-jedi jedi auto-package-update iedit xterm-color copilot quelpa editorconfig grip-mode rainbow-delimiters persistent-scratch company-web smartscan undo-tree ace-window use-package))
'(persistent-scratch-autosave-mode t)
'(pomm-audio-enabled nil)
'(project-switch-commands
'((project-find-file "Find file" nil)
(project-find-regexp "Find regexp" nil)
(project-find-dir "Find directory" nil)
(project-shell "Shell" nil)
(magit-project-status "Magit" 109)))
'(project-vc-ignores '("venv"))
'(projectile-globally-ignored-directories '(".git" "node_modules" "vendor"))
'(pytest-global-name "poetry run pytest")
'(python-interpreter "python3")
'(ring-bell-function 'ignore)
'(rubocopfmt-on-save-use-lsp-format-buffer t)
'(rust-format-on-save t)
'(rust-ts-mode-indent-offset 2)
'(save-place-mode t)
'(savehist-mode t)
'(scroll-bar-mode nil)
'(search-default-mode 'char-fold-to-regexp)
'(sentence-end-double-space nil)
'(sh-shell-file "/opt/homebrew/bin/bash")
'(shell-file-name "/opt/homebrew/bin/bash")
'(show-paren-mode t)
'(tab-width 4)
'(tool-bar-mode nil)
'(undo-tree-auto-save-history nil)
'(uniquify-buffer-name-style 'forward nil (uniquify))
'(use-package-always-ensure nil)
'(vc-directory-exclusion-list
'("SCCS" "RCS" "CVS" "MCVS" ".src" ".svn" ".git" ".hg" ".bzr" "_MTN" "_darcs" "{arch}" "node_modules" "dist" "venv"))
'(version-control t))
(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.
'(kubel-status-terminating ((t (:foreground "RoyalBlue1")))))
(add-hook 'shell-mode-hook
(lambda ()
;; Disable font-locking in this buffer to improve performance
(font-lock-mode -1)
;; Prevent font-locking from being re-enabled in this buffer
(make-local-variable 'font-lock-function)
(setq font-lock-function (lambda (_) nil))
(add-hook 'comint-preoutput-filter-functions 'xterm-color-filter nil t)))
(use-package all-the-icons
:if (display-graphic-p))
(add-to-list 'load-path
(expand-file-name "~/.emacs.d/emacs-kubectx-mode"))
(setq kubectx-mode-line-string-format "[%C:%N]")
(require 'kubectx-mode)
(kubectx-mode 1)
;; Auto update at lunch
(auto-package-update-at-time "11:30")
(setq default-directory "~/workspace/")
;; Hooks for `prog-mode'
(add-hook 'prog-mode-hook #'display-line-numbers-mode)
(add-hook 'prog-mode-hook #'breadcrumb-mode)
;; Quickly jumps between other symbols found at point in Emacs
;; M-n and M-p move between symbols and type M-' to replace all symbols in the buffer matching the one under point, and C-u M-' to replace symbols in your current defun only (as used by narrow-to-defun.)
(add-hook 'prog-mode-hook #'smartscan-mode)
;; Hooks for `text-mode'
(add-hook 'text-mode-hook #'display-line-numbers-mode)
(add-hook 'text-mode-hook #'flyspell-mode)
;; Keybindings
(global-set-key [M-up] 'move-text-up)
(global-set-key [M-down] 'move-text-down)
(global-set-key (kbd "C-c C-c") 'compile)
(global-set-key (kbd "M-z") 'zap-up-to-char)
(use-package markdown-mode
:ensure t
:mode ("README\\.md\\'" . gfm-mode)
:init (setq markdown-command "pandoc"))
;;:init (setq markdown-command "multimarkdown"))
;; Ensure Emacs responds to keystrokes in the same way as other OS X apps
;;(setq default-input-method "MacOSX")
;;(setq mac-option-key-is-meta nil)
;;(setq mac-right-option-modifier nil)
;;(setq mac-option-modifier 'meta)
;; https://www.emacswiki.org/emacs/MetaKeyProblems#h5o-18
;;(setq mac-option-key-is-meta nil)
;;(setq mac-command-key-is-meta t)
;;(setq mac-command-modifier 'meta)
;;(setq mac-option-modifier nil)
;; Terje sin løsing
;;(setq mac-option-modifier nil)
;;(setq mac-command-modifier 'meta)
;; Nullstill
;;(setq mac-option-modifier 'meta)
;;(setq mac-command-modifier nil)
(setq mac-allow-anti-aliasing t)
(set-face-font 'default "Andale Mono-14")
(set-fontset-font t 'symbol "Apple Color Emoji")
;; Midnight
;; Kills buffers not used the last 24h
(require 'midnight)
(setq clean-buffer-list-delay-general 1)
(add-hook 'midnight-hook (lambda ()
(shell-command "gh gist edit 24420c7ceee5f25a82d14255b7990766 --add ~/.emacs.d/init.el")))
(add-hook 'midnight-hook (lambda ()
(shell-command "gh gist edit 24420c7ceee5f25a82d14255b7990766 --add ~/.emacs.d/kyb.el")))
(add-hook 'midnight-hook (lambda ()
(shell-command "gh gist edit 24420c7ceee5f25a82d14255b7990766 --add ~/.bash_profile")))
(add-hook 'midnight-hook (lambda ()
(shell-command "gh gist edit 24420c7ceee5f25a82d14255b7990766 --add ~/.bashrc")))
;; Colors compilatiton-mode with ANSI colors
(use-package ansi-color
:hook (compilation-filter . ansi-color-compilation-filter))
;; For setting $PATH correctly in shell
(use-package exec-path-from-shell
:init (setq exec-path-from-shell-variables '("PATH" "KUBECONFIG" "HISTFILE" "HISTCONTROL" "EDITOR" "GOPATH" "LANG" "PAGER" "LESS"))
:config (exec-path-from-shell-initialize))
;; Bash and shell completion
(autoload 'bash-completion-dynamic-complete
"bash-completion"
"BASH completion hook")
(add-hook 'shell-dynamic-complete-functions
'bash-completion-dynamic-complete)
(coterm-mode)
(defun kill-kubel-buffers ()
"Kill all kubel buffers."
(interactive)
(kill-matching-buffers "\*kubel.*" nil 'NO-ASK))
(defun kill-other-buffers ()
"Kill all other buffers than the one you are in now."
(interactive)
(mapc 'kill-buffer (delq (current-buffer) (buffer-list))))
;; Change intention for JSON
(add-hook 'json-mode-hook
(lambda ()
(make-local-variable 'js-indent-level)
(setq js-indent-level 2)))
;; JSON schemas
(add-hook 'json-mode-hook
(lambda ()
(setq-default eglot-workspace-configuration
'(:yaml ( :format (:enable t)
:validate t
:hover t
:completion t
:schemas (https://storage.googleapis.com/nais-json-schema-2c91/nais-all.json ["nais.yaml", "nais.yml", "naiserator.yaml", "naiserator.yml"]
https://json.schemastore.org/yamllint.json ["/*.yml"])
:schemaStore (:enable t))
))))
(use-package jsonian
:ensure nil
:after so-long
:custom
(jsonian-no-so-long-mode))
;; magit
(add-to-list 'load-path
(expand-file-name "~/.emacs.d/mygit.el"))
(load "~/.emacs.d/mygit.el")
(use-package magit
:config
(require 'magit-patch)
(transient-insert-suffix
'magit-patch "r" '("b" "Save diff as patch to buffer" my/magit-write-patch-to-buffer))
(transient-insert-suffix
'magit-patch "r" '("w" "Copy diff as patch to kill-ring" my/magit-copy-patch-kill-ring))
:hook (('magit-pre-refresh-hook 'diff-hl-magit-pre-refresh)
'magit-post-refresh-hook 'diff-hl-magit-post-refresh)
:bind (("C-x g" . magit-status)
("C-x M-b" . magit-blame)))
(use-package forge
:after magit)
(use-package magit-todos
:after magit
:config (magit-todos-mode 1))
;; git mode in gutter
(global-diff-hl-mode)
(global-set-key [left-fringe mouse-1] 'diff-hl-show-hunk--click)
(use-package link-hint
:ensure t
:bind
("C-c l o" . link-hint-open-link)
("C-c l c" . link-hint-copy-link)
("C-c l p" . link-hint-open-link-at-point))
;; company setup
(add-hook 'after-init-hook 'global-company-mode)
;; GPG
(require 'epa-file)
;; Input an arbitrary amount of consecutive chars, jump to the first one with a tree.
(global-set-key (kbd "C-:") 'avy-goto-char-timer)
;; Input zero chars, jump to a line start with a tree.
(global-set-key (kbd "M-g M-g") 'avy-goto-line)
;; Input one char at word start, jump to a word start with a tree.
(global-set-key (kbd "M-g w") 'avy-goto-word-1)
;; expand region
(global-set-key (kbd "C-=") 'er/expand-region)
(defalias 'yes-or-no-p 'y-or-n-p)
(defadvice kill-region (before slick-cut activate compile)
"When called interactively with no active region, kill a single line instead."
(interactive
(if mark-active (list (region-beginning) (region-end))
(list (line-beginning-position)
(line-beginning-position 2)))))
;; (global-set-key (kbd "C-c p") 'pop-to-mark-command) ; originally pop mark with C-u C-space
(setq set-mark-command-repeat-pop t)
;; Copied from http://emacsredux.com/blog/2013/05/22/smarter-navigation-to-the-beginning-of-a-line/
(defun my-smarter-move-beginning-of-line (arg)
"Move point back to indentation of beginning of line.
Move point to the first non-whitespace character on this line.
If point is already there, move to the beginning of the line.
Effectively toggle between the first non-whitespace character and
the beginning of the line.
If ARG is not nil or 1, move forward ARG - 1 lines first. If
point reaches the beginning or end of the buffer, stop there."
(interactive "^p")
(setq arg (or arg 1))
;; Move lines first
(when (/= arg 1)
(let ((line-move-visual nil))
(forward-line (1- arg))))
(let ((orig-point (point)))
(back-to-indentation)
(when (= orig-point (point))
(move-beginning-of-line 1))))
;; remap C-a to `smarter-move-beginning-of-line'
(global-set-key [remap move-beginning-of-line]
'my-smarter-move-beginning-of-line)
;; cycle through amounts of spacing
(global-set-key (kbd "M-SPC") 'cycle-spacing)
;; From https://blog.lambda.cx/posts/emacs-align-columns/
(defun my-align-non-space (BEG END)
"Align non-space columns in region BEG END."
(interactive "r")
(align-regexp BEG END "\\(\\s-*\\)\\S-+" 1 1 t))
;; Setting arguments for the diff tool used
(setq vc-diff-switches '("-b" "-B" "-u"))
(setq vc-git-diff-switches nil)
;; Make files executable if the first file has a shebang (ex: #!/bin/bash#)
(add-hook 'after-save-hook
'executable-make-buffer-file-executable-if-script-p)
;; TODO: Hva gjør denne?
(use-package emacs
:init
;; Add prompt indicator to `completing-read-multiple'.
;; Alternatively try `consult-completing-read-multiple'.
(defun crm-indicator (args)
(cons (concat "[CRM] " (car args)) (cdr args)))
(advice-add #'completing-read-multiple :filter-args #'crm-indicator)
;; Do not allow the cursor in the minibuffer prompt
(setq minibuffer-prompt-properties
'(read-only t cursor-intangible t face minibuffer-prompt))
(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
;; Enable recursive minibuffers
(setq enable-recursive-minibuffers t))
;; Terraform-mode
;;(use-package terraform-mode
;; :hook (terraform-format-on-save-mode))
(add-hook 'terraform-mode-hook #'terraform-format-on-save-mode)
;; Ruby
(use-package ruby
:hook
(ruby-mode . eglot-ensure)
(ruby-ts-mode . eglot-ensure))
(add-hook 'ruby-mode-hook
(lambda ()
(set (make-local-variable 'compile-command)
(concat "ruby " buffer-file-name))))
(add-hook 'ruby-mode-hook #'rubocopfmt-mode)
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode))
;; Python
(use-package elpy
:ensure t
:init
(elpy-enable))
;; (use-package python-black
;; :demand t
;; :after python
;; :hook (python-mode . python-black-on-save-mode-enable-dwim))
(use-package python
:bind (:map python-mode-map
("C-c C-c" . compile)
("C-c a" . pytest-all)
("C-c m" . pytest-module)
("C-c ." . pytest-one)
("C-c c" . pytest-again)
("C-c d" . pytest-directory)
("C-c p a" . pytest-pdb-all)
("C-c p m" . pytest-pdb-module)
("C-c p." . pytest-pdb-one)))
(require 'py-autopep8)
(add-hook 'elpy-mode-hook 'py-autopep8-enable-on-save)
;; Go
(use-package go-mode
:bind (:map go-mode-map
("C-c a" . go-test-current-project)
("C-c f" . go-test-current-file)
("C-c ." . go-test-current-test)))
;; Flycheck
(when (require 'flycheck nil t)
(setq elpy-modules (delq 'elpy-module-flymake elpy-modules))
(add-hook 'elpy-mode-hook 'flycheck-mode))
;; ivy
(use-package ivy
:defer 0.1
:bind (("C-c C-r" . ivy-resume))
:config (ivy-mode))
(use-package ivy-rich
:after ivy
:init (ivy-rich-mode 1)
:custom
(ivy-virtual-abbreviate 'full
ivy-rich-path-style 'abbrev))
(use-package counsel
:after ivy
:config (counsel-mode))
(use-package swiper
:after ivy
:bind (("C-s" . swiper)
("C-r" . swiper)))
(use-package all-the-icons-ivy-rich
:after ivy
:ensure t
:init (all-the-icons-ivy-rich-mode 1))
;; Enable vertico
(use-package vertico
;; :custom
;; (vertico-scroll-margin 0) ;; Different scroll margin
;; (vertico-count 20) ;; Show more candidates
;; (vertico-resize t) ;; Grow and shrink the Vertico minibuffer
;; (vertico-cycle t) ;; Enable cycling for `vertico-next/previous'
:init
(vertico-mode))
;; switch to buffer
(global-set-key (kbd "M-o") 'ace-window)
(use-package dired-single
:commands dired-single-buffer dired-single-buffer-mouse
:defines dired-mode-map
:init
(add-hook 'dired-mode-hook
(lambda ()
;; Enable all commands
(setq disabled-command-function nil)
(define-key dired-mode-map [remap dired-find-file]
'dired-single-buffer)
(define-key dired-mode-map [remap dired-mouse-find-file-other-window]
'dired-single-buffer-mouse)
(define-key dired-mode-map [remap dired-up-directory]
'dired-single-up-directory)
(define-key dired-mode-map [return] 'dired-single-buffer)
(define-key dired-mode-map [down-mouse-1] 'dired-single-buffer-mouse)
(define-key dired-mode-map [^]
(lambda ()
(interactive)
(dired-single-buffer "..")))
;; Auto-refresh dired on file change
(auto-revert-mode)
(setq-default auto-revert-interval 1)
(auto-revert-set-timer))))
(use-package rainbow-mode
:hook (prog-mode . rainbow-mode))
;; Co-pilot
;; Based on function from https://robert.kra.hn/posts/2023-02-22-copilot-emacs-setup/
(defun copilot-complete-or-accept ()
"Command that either triggers a completion or accepts one if one
is available."
(interactive)
(if (copilot--overlay-visible)
(progn
(copilot-accept-completion))
(copilot-complete)))
(use-package copilot
:quelpa (copilot :fetcher github
:repo "copilot-emacs/copilot.el"
:branch "main"
:files ("*.el"))
:bind (:map copilot-completion-map
("<tab>" . copilot-accept-completion)
("C-<tab>" . 'copilot-accept-completion-by-word)
("C-S-<tab>" . 'copilot-accept-completion-by-line)
("M-n" . 'copilot-next-completion)
("M-p" . 'copilot-previous-completion)
("C-<return>" . 'copilot-complete-or-accept))
:hook (prog-mode . copilot-mode))
(setq copilot-version "1.27.0")
(use-package copilot-chat
:quelpa (copilot-chat :fetcher github
:repo "chep/copilot-chat.el"
:files ("*.el")))
;; Treesit
(setq treesit-language-source-alist
'((bash "https://github.com/tree-sitter/tree-sitter-bash")
(rust "https://github.com/tree-sitter/tree-sitter-rust")
(elisp "https://github.com/Wilfred/tree-sitter-elisp")
(go "https://github.com/tree-sitter/tree-sitter-go")
(html "https://github.com/tree-sitter/tree-sitter-html")
(javascript "https://github.com/tree-sitter/tree-sitter-javascript" "master" "src")
(json "https://github.com/tree-sitter/tree-sitter-json")
(make "https://github.com/alemuller/tree-sitter-make")
(markdown "https://github.com/ikatyang/tree-sitter-markdown")
(python "https://github.com/tree-sitter/tree-sitter-python")
(toml "https://github.com/tree-sitter/tree-sitter-toml")
(tsx "https://github.com/tree-sitter/tree-sitter-typescript" "master" "tsx/src")
(proto "https://github.com/mitchellh/tree-sitter-proto" "main" "src")
(typescript "https://github.com/tree-sitter/tree-sitter-typescript" "master" "typescript/src")
(yaml "https://github.com/ikatyang/tree-sitter-yaml")))
;; Eglot
(require 'project)
(defun project-find-go-module (dir)
(when-let ((root (locate-dominating-file dir "go.mod")))
(cons 'go-module root)))
(cl-defmethod project-root ((project (head go-module)))
(cdr project))
(add-hook 'project-find-functions #'project-find-go-module)
;; Optional: load other packages before eglot to enable eglot integrations.
(require 'company)
(require 'yasnippet)
(require 'go-mode)
(use-package eglot
:config
(add-to-list 'eglot-server-programs '((sh-mode bash-ts-mode) . ("bash-language-server" "start")))
(add-to-list 'eglot-server-programs '((kotlin-mode kotlin-ts-mode) . ("kotlin-language-server")))
(add-to-list 'eglot-server-programs '((js-mode) . ("typescript-language-server --stdio")))
(add-to-list 'eglot-server-programs '((js-ts-mode) . ("typescript-language-server --stdio")))
;; Python? vfork? Bytt til python-mode, kjør eglot, velg pylsp (eller noe), rydd opp?
:hook
(sh-mode . eglot-ensure)
(bash-ts-mode . eglot-ensure)
(kotlin-ts-mode . eglot-ensure)
(python-mode . eglot-ensure)
(js-mode . eglot-ensure)
(js-ts-mode . eglot-ensure)
(go-mode . eglot-ensure)
(rust-mode . eglot-ensure)
(ruby-mode . eglot-ensure)
:bind (("C-c e a" . eglot-code-actions)
("C-c e r" . eglot-rename)
("C-c e o" . eglot-code-action-organize-imports)))
;; ("C-c e f" . eglot-code-actions "source.organizeImports")
;; (require 'eglot)
;;(add-hook 'go-mode-hook 'eglot-ensure)
;; Rust
;;(add-hook 'rust-mode-hook 'eglot-ensure)
;; these lines are only needed if you choose to use go-ts-mode.
(add-hook 'go-ts-mode-hook 'flymake-mode 8)
(add-hook 'go-ts-mode-hook 'flymake-show-buffer-diagnostics 9)
(add-hook 'go-ts-mode-hook 'eglot-ensure 10)
;; Optional: install eglot-format-buffer as a save hook.
;; The depth of -10 places this before eglot's willSave notification,
;; so that that notification reports the actual contents that will be saved.
(defun eglot-format-buffer-on-save ()
(add-hook 'before-save-hook #'eglot-format-buffer -10 t))
(add-hook 'go-mode-hook #'eglot-format-buffer-on-save)
(add-hook 'go-ts-mode-hook #'eglot-format-buffer-on-save)
(add-hook 'go-mode-hook
(lambda () (setq-default eglot-workspace-configuration
'((:gopls .
((staticcheck . t)
(matcher . "CaseSensitive")))))))
(defun own/eglot-organize-imports ()
(call-interactively 'eglot-code-action-organize-imports))
(defun own/before-saving-go ()
(add-hook 'before-save-hook #'eglot-format-buffer -10 t)
(add-hook 'before-save-hook #'own/eglot-organize-imports nil t))
(add-hook 'go-mode-hook #'own/before-saving-go)
(add-hook 'before-save-hook
(lambda ()
(call-interactively 'eglot-code-action-organize-imports))
nil t)
(add-to-list 'display-buffer-alist
'("^\\*Flymake diagnostics"
(display-buffer-reuse-window display-buffer-pop-up-window)
(window-height . 10)))
;; Eglot end
(use-package which-key
:config
(which-key-mode))
;; yaml-mode
(use-package yaml
:hook highlight-indentation-mode)
(add-hook 'yaml-mode-hook
(lambda ()
(set (make-local-variable 'compile-command)
(concat "kubectl apply -f " buffer-file-name))))
;; TODO: https://jointhefreeworld.org/blog/articles/emacs/yaml-schemas-in-emacs-eglot/
;; kubel
(add-to-list 'load-path
(expand-file-name "~/.emacs.d/kyb.el"))
(load "~/.emacs.d/kyb.el")
(use-package kubel
:bind (
(:map kubel-mode-map
("RET" . kybel-describe-popup)
("N" . kubel-set-namespace)
("P" . kubel-port-forward-pod)
("R" . kybel-set-resource-popup)
("M-s" . kubel-scale-replicas)
("S" . #'tabulated-list-sort)
("C-b" . #'tabulated-list-previous-column)
("C-f" . #'tabulated-list-next-column)
("n" . #'next-line)
("p" . #'previous-line))))
;; Enable rich annotations using the Marginalia package
(use-package marginalia
:ensure t
;; Bind `marginalia-cycle' locally in the minibuffer. To make the binding
;; available in the *Completions* buffer, add it to the
;; `completion-list-mode-map'.
:bind (:map minibuffer-local-map
("M-A" . marginalia-cycle))
;; The :init section is always executed.
:init
;; Marginalia must be activated in the :init section of use-package such that
;; the mode gets enabled right away. Note that this forces loading the
;; package.
(marginalia-mode))
(use-package tramp
:defines (explicit-sh-args tramp-histfile-override)
:init (setq tramp-default-method "sshx"
tramp-histfile-override t
;;explicit-shell-file-name "sh"
explicit-sh-args '("-l")))
(defun add-string-to-end-of-lines-in-region (start end string)
"Prompt for string, add it to end of lines in the region"
(interactive
(list (region-beginning)
(region-end)
(read-string (format-prompt
"String rectangle"
(or (car string-rectangle-history) ""))
nil 'string-rectangle-history
(car string-rectangle-history)
'inherit-input-method)))
(goto-char start)
(while (<= (point) end)
(end-of-line)
(insert string)
(forward-line 1)))
(global-set-key (kbd "C-x r e") 'add-string-to-end-of-lines-in-region)
;; Verb
(with-eval-after-load 'org
(define-key org-mode-map (kbd "C-c C-r") verb-command-map))
(require 'transient)
(defun kybel-describe-resource ()
"Describe the resource under the cursor."
(interactive)
(let* ((resource (kubel--get-resource-under-cursor))
(process-name (format "kubel - %s - %s" kubel-resource resource)))
(kubel--exec process-name (list "describe" kubel-resource (kubel--get-resource-under-cursor)) t)
(yaml-mode)
(view-mode)
(goto-char (point-min))))
;; Let you list all resources of one kind cross namespaces
(transient-define-prefix kybel-describe-popup ()
"Kubel Describe Menu"
["Actions"
("RET" "Describe" kybel-describe-resource)
("e" "Edit" kubel-get-resource-details)])
(defvar-local kubel-all-namespaces nil
"If we should list all resources of one kind.")
(defvar-local kubel-watch-resource nil
"If we should watch the resource.")
;; We have added checks for postfixes, so that we know later if we want to watch or see all resources in the cluster
(defun kubel-set-resource (&optional refresh)
"Set the resource.
If called with a prefix argument REFRESH, refreshes
the context caches, including the cached resource list."
(interactive "P")
(when refresh (kubel--invalidate-context-caches))
(when (member "--all-namespaces" (transient-args 'kybel-set-resource-popup)) (setq kubel-all-namespaces t))
(when (member "--watch" (transient-args 'kybel-set-resource-popup)) (setq kubel-watch-resource t))
(let* ((current-buffer-name (kubel--buffer-name))
(resource-list (kubel--kubernetes-resources-list))
(kubel--buffer (get-buffer current-buffer-name))
(last-default-directory (when kubel--buffer (with-current-buffer kubel--buffer default-directory))))
(with-current-buffer (clone-buffer)
(setq kubel-resource
(completing-read "Select resource: " resource-list))
(switch-to-buffer (current-buffer))
(kubel-refresh last-default-directory))))
(defun kybel--get-command-postfix ()
"Return the command postfix."
(concat
(if kubel-all-namespaces
(progn
(setq kubel-all-namespaces nil)
" --all-namespaces"))
(if kubel-watch-resource
(progn
(setq kubel-watch-resource nil)
" --watch"))))
;; We need to add postfix to the command, as -A/-w is not a prefix option
(defun kubel--populate-list ()
"Return a list with a tabulated list format and \"tabulated-list-entries\"."
(let* ((body (kubel--exec-to-string (concat (kubel--get-command-prefix) " get " kubel-resource (kybel--get-command-postfix))))
(entrylist (kubel--parse-body body)))
(when (string-prefix-p "No resources found" body)
(message "No resources found")) ;; TODO exception here
(list (kubel--get-list-format entrylist) (kubel--get-list-entries entrylist))))
(transient-define-prefix kybel-set-resource-popup ()
"Kubel Set Resource Menu"
["Arguments"
("-A" "All namespaces" "--all-namespaces")]
;; ("-w" "Watch resource" "--watch")] ; Not workin as watch is holding the process
["Actions"
("RET" "Continue" kubel-set-resource)])
(defun kubel--populate-list ()
"Return a list with a tabulated list format and \"tabulated-list-entries\"."
(let* ((body (kubel--exec-to-string (concat (kubel--get-command-prefix) " get " kubel-resource)))
(entrylist (kubel--parse-body body)))
(when (string-prefix-p "No resources found" body)
(message "No resources found")) ;; TODO exception here
(list (kubel--get-list-format entrylist) (kubel--get-list-entries entrylist))))
(defun kubel--exec-to-string (cmd)
"Replace \"shell-command-to-string\" to log to process buffer.
CMD is the command string to run."
(kubel--log-command "kubectl-command" cmd)
(with-output-to-string
(with-current-buffer standard-output
(shell-command cmd t "*kubel stderr*"))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment