Last active
February 5, 2026 00:02
-
-
Save Kyrremann/24420c7ceee5f25a82d14255b7990766 to your computer and use it in GitHub Desktop.
My dotfiles
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 TERM=xterm-256color | |
| export TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/var/run/docker.sock | |
| export DOCKER_HOST="unix://${HOME}/.colima/docker.sock" | |
| export PATH=/opt/homebrew/opt/postgresql@17/bin:/Users/kyrremann/.local/bin:/Users/kyrremann/.local/share/mise/shims:/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 | |
| # The next line enables shell command completion for gcloud. | |
| . '/usr/local/bin/google-cloud-sdk/completion.bash.inc' | |
| . '/usr/local/bin/google-cloud-sdk/path.bash.inc' | |
| eval "$(/opt/homebrew/bin/brew shellenv)" | |
| [[ -r "/opt/homebrew/etc/profile.d/bash_completion.sh" ]] && . "/opt/homebrew/etc/profile.d/bash_completion.sh" | |
| . "$HOME/.cargo/env" | |
| # Scaleway CLI autocomplete initialization. | |
| eval "$(scw autocomplete script shell=bash)" | |
| if [ -s ./.bashrc ] | |
| then | |
| source ./.bashrc | |
| else | |
| echo "No .bashrc found" | |
| fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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" | |
| export HISTCONTROL=ignoreboth | |
| export EDITOR="emacsclient" | |
| export LANG="en_US.UTF-8" | |
| export PAGER=cat | |
| export KUBECTX_CURRENT_FGCOLOR="$(tput bold)$(tput setaf 6)" # blue text | |
| export KUBECTX_CURRENT_BGCOLOR=$(tput setab 7) # white background | |
| ### ### | |
| # 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]/' | |
| } | |
| ### ### | |
| # 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" | |
| eval "$(/opt/homebrew/bin/mise activate bash)" # added by https://mise.run/bash |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;; -*- lexical-binding: t; -*- | |
| (require 'json) | |
| (require 'url) | |
| (defvar gitmoji-json-url "https://raw.githubusercontent.com/carloscuesta/gitmoji/refs/heads/master/packages/gitmojis/src/gitmojis.json") | |
| (defvar gitmoji-json-local "~/.emacs.d/gitmojis.json") | |
| (defun gitmoji--download-emoji-json () | |
| "Download Gomoji JSON from Githun if not present." | |
| (unless (file-exists-p gitmoji-json-local) | |
| (url-copy-file gitmoji-json-url gitmoji-json-local t))) | |
| (defun gitmoji--load-emojis () | |
| "Load Gomojis from local file." | |
| (gitmoji--download-emoji-json) | |
| (with-temp-buffer | |
| (insert-file-contents gitmoji-json-local) | |
| (let ((json-array-type 'list)) | |
| (alist-get 'gitmojis (json-read))))) | |
| (defun gitmoji () | |
| "Prompt for an Gomoji and insert it at point." | |
| (interactive) | |
| (let* ((emojis (gitmoji--load-emojis)) | |
| (choices (mapcar (lambda (e) | |
| (let ((emoji (alist-get 'emoji e)) | |
| (name (alist-get 'name e)) | |
| (desc (alist-get 'description e))) | |
| (cons (format "%s %s — %s" emoji name desc) emoji))) | |
| emojis)) | |
| (choice (completing-read "Pick emoji: " (mapcar #'car choices) nil t)) | |
| (emoji-str (cdr (assoc choice choices)))) | |
| (if (string= (buffer-name) "COMMIT_EDITMSG") | |
| (insert (concat emoji-str ": ")) | |
| (insert emoji-str)))) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;;; -*- lexical-binding: t -*- | |
| (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. | |
| '(aw-keys '(97 115 100 102 103 104 106 107 108)) | |
| '(backup-by-copying t) | |
| '(backup-directory-alist '(("." . "~/.emacs.d/backups"))) | |
| '(clean-buffer-list-delay-general 1) | |
| '(clean-buffer-list-kill-buffer-names | |
| '("*Help*" "*Apropos*" "*Buffer List*" "*Compile-Log*" "*info*" "*vc*" | |
| "*vc-diff*" "*diff*" "*kubel*")) | |
| '(conf-mode-hook '(display-line-numbers-mode prettify-symbols-mode) t) | |
| '(copilot-indent-offset-warning-disable t) | |
| '(copilot-max-char -1) | |
| '(custom-safe-themes | |
| '("8fbf2d585f1138caaafa9e523fa3a20614c1d1dcc6002c9808c3e40028e21df4" | |
| "488b82a8d9ace0aea8a6825db144e3c65c4f1ef3e090b618bf311d9cdb513322" | |
| "3656585faa5bd9925c0ee134b5eecf6d6a45ee2a2e81e633fa7a9a0659fdc095" | |
| "317f9fc9b30ce2d8064965f1a3cf8645ee3e8dc26dfcdc9f0e2ead337f37cac3" | |
| "7e98dc1aa7f5db0557691da690c38d55e83ddd33c6d268205d66e430d57fb982" | |
| "8dbbcb2b7ea7e7466ef575b60a92078359ac260c91fe908685b3983ab8e20e3f" | |
| default)) | |
| '(default-frame-alist nil) | |
| '(delete-old-versions t) | |
| '(desktop-save-mode t) | |
| '(dired-kill-when-opening-new-dired-buffer t) | |
| '(display-buffer-base-action '(nil)) | |
| '(display-time-24hr-format t) | |
| '(display-time-default-load-average nil) | |
| '(display-time-mode t) | |
| '(global-auto-revert-mode t) | |
| '(global-undo-tree-mode t) | |
| '(go-ts-mode-build-tags '("integration_test")) | |
| '(go-ts-mode-indent-offset 2) | |
| '(highlight-indent-guides-method 'fill) | |
| '(inhibit-default-init t) | |
| '(initial-buffer-choice t) | |
| '(isearch-lazy-count t) | |
| '(ivy-count-format "(%d/%d) ") | |
| '(ivy-sort-matches-functions-alist | |
| '((t) (ivy-completion-in-region . ivy--shorter-matches-first) | |
| (ivy-switch-buffer . ivy-sort-function-buffer))) | |
| '(ivy-use-virtual-buffers 'recentf) | |
| '(js-indent-level 2) | |
| '(kubectx-mode-line-string-format "[%C:%N]" t) | |
| '(link-hint-action-fallback-commands | |
| '(:open | |
| (lambda nil | |
| (condition-case _ | |
| (progn (browse-url (git-link-homepage "origin")) t) | |
| (error nil))))) | |
| '(magit-clone-default-directory 'my/magit-clone-default-directory) | |
| '(magit-clone-name-alist | |
| '(("\\`\\(?:github:\\|gh:\\)?\\([^:]+\\)\\'" "github.com" | |
| "github.user") | |
| ("\\`\\(?:gitlab:\\|gl:\\)\\([^:]+\\)\\'" "gitlab.com" | |
| "gitlab.user") | |
| ("\\`\\(?:sourcehut:\\|sh:\\)\\([^:]+\\)\\'" "git.sr.ht" | |
| "sourcehut.user") | |
| ("^(nais|navikt)\\/([^:]+)$" "github.com" "github.user"))) | |
| '(midnight-hook | |
| '(clean-buffer-list | |
| (lambda nil | |
| (shell-command | |
| "gh gist edit 24420c7ceee5f25a82d14255b7990766 --add ~/.emacs.d/kyb.el")) | |
| (lambda nil | |
| (shell-command | |
| "gh gist edit 24420c7ceee5f25a82d14255b7990766 --add ~/.emacs.d/init.el")) | |
| (lambda nil | |
| (shell-command | |
| "gh gist edit 24420c7ceee5f25a82d14255b7990766 --add ~/.emacs.d/my.el")) | |
| (lambda nil | |
| (shell-command | |
| "gh gist edit 24420c7ceee5f25a82d14255b7990766 --add ~/.emacs.d/gitmoji.el")) | |
| (lambda nil | |
| (shell-command | |
| "gh gist edit 24420c7ceee5f25a82d14255b7990766 --add ~/.bash_profile")) | |
| (lambda nil | |
| (shell-command | |
| "gh gist edit 24420c7ceee5f25a82d14255b7990766 --add ~/.bashrc")))) | |
| '(midnight-mode t) | |
| '(package-archives | |
| '(("gnu" . "https://elpa.gnu.org/packages/") | |
| ("nongnu" . "https://elpa.nongnu.org/nongnu/") | |
| ("melpa" . "https://melpa.org/packages/"))) | |
| '(package-install-upgrade-built-in t) | |
| '(package-selected-packages | |
| '(ace-window auto-package-update breadcrumb breadcrumb-mode company | |
| copilot copilot-chat diff-hl emojify expand-region | |
| git-link go-dlv go-mode go-snippets gotest-ts gptel | |
| graphql-mode highlight-indent-guides jsonian | |
| kotlin-ts-mode kubectx-mode kubel link-hint magit | |
| marginalia mistty modus-themes move-text orderless | |
| rainbow-delimiters rainbow-mode rust-mode | |
| sqlite-mode-extras svelte-mode terraform-mode tidal | |
| undo-tree vertico yasnippet-snippets)) | |
| '(prog-mode-hook | |
| '(display-line-numbers-mode prettify-symbols-mode subword-mode)) | |
| '(project-file-history-behavior 'relativize) | |
| '(project-switch-commands | |
| '((project-find-file "Find file" nil) | |
| (project-find-regexp "Find regexp" nil) | |
| (project-find-dir "Find directory" nil) | |
| (mistty-in-project "Shell" 115) | |
| (magit-project-status "Magit" 109))) | |
| '(project-vc-ignores '(".git" "venv" "node_modules" "vendor")) | |
| '(ring-bell-function 'ignore) | |
| '(rust-always-locate-project-on-open t) | |
| '(rust-format-on-save t) | |
| '(rust-rustfmt-switches '("--edition=2024")) | |
| '(savehist-mode t) | |
| '(scroll-bar-mode nil) | |
| '(set-mark-command-repeat-pop t) | |
| '(shell-file-name "/opt/homebrew/bin/fish") | |
| '(split-height-threshold 160) | |
| '(switch-window-shortcut-style 'alphabet) | |
| '(tab-width 2) | |
| '(terraform-command "terraform") | |
| '(terraform-format-on-save t) | |
| '(text-mode-hook | |
| '(display-line-numbers-mode flyspell-mode text-mode-hook-identify)) | |
| '(undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo-tree-history"))) | |
| '(undo-tree-visualizer-diff t) | |
| '(use-package-always-ensure t) | |
| '(use-short-answers t) | |
| '(yaml-indent-offset 2)) | |
| (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. | |
| '(ansi-color-bright-yellow ((t (:background "gray100" :foreground "#884900")))) | |
| '(ansi-color-yellow ((t (:background "gray100" :foreground "#6f5500")))) | |
| '(term ((t (:background "#ffffff" :foreground "#000000")))) | |
| '(term-color-yellow ((t (:background "white" :foreground "#6f5500"))))) | |
| (load "~/.emacs.d/kyb.el") | |
| (load "~/.emacs.d/my.el") | |
| (load "~/.emacs.d/gitmoji.el") | |
| (load-theme 'modus-operandi) | |
| (set-face-font 'default "Andale Mono-14") | |
| (set-fontset-font t 'symbol "Apple Color Emoji") | |
| ;; Proper Mac keybindings | |
| (setq mac-right-option-modifier nil) | |
| ;; Keybindings | |
| (global-set-key (kbd "C-c C-c") 'compile) | |
| (global-set-key (kbd "M-z") 'zap-up-to-char) | |
| ;; setq | |
| (setq default-directory "~/workspace/") | |
| ;; TODO: Dette fra copilot funker ikke | |
| (defun my/slick-cut-a (orig beg end &rest args) | |
| "" | |
| (interactive | |
| (if (use-region-p) | |
| (apply orig beg end args) | |
| (apply orig (line-beginning-position) | |
| (line-beginning-position 2) args)))) | |
| (advice-add 'kill-region :around #'my/slick-cut-a) | |
| (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))))) | |
| ;;; only use-package after this line | |
| (use-package emacs | |
| :init | |
| ;; Add prompt indicator to `completing-read-multiple'. | |
| ;; Prepending [CRM] to the prompt string to help users quickly recognize that the prompt supports multiple selections | |
| (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) | |
| ;; Vertico minibuffer configurations. | |
| :custom | |
| ;; Enable context menu. `vertico-multiform-mode' adds a menu in the minibuffer | |
| ;; to switch display modes. | |
| (context-menu-mode t) | |
| ;; Support opening new minibuffers from inside existing minibuffers. | |
| (enable-recursive-minibuffers t) | |
| ;; Hide commands in M-x which do not work in the current mode. Vertico | |
| ;; commands are hidden in normal buffers. This setting is useful beyond | |
| ;; Vertico. | |
| (read-extended-command-predicate #'command-completion-default-include-p) | |
| ;; Do not allow the cursor in the minibuffer prompt | |
| (minibuffer-prompt-properties | |
| '(read-only t cursor-intangible t face minibuffer-prompt))) | |
| ;; end Vertico | |
| (use-package files | |
| :ensure nil | |
| :hook (after-save . executable-make-buffer-file-executable-if-script-p)) | |
| (use-package vc | |
| :config | |
| ;; ignore whitespace changes (-b) | |
| ;; ignore changes whose lines are all blank (-B) | |
| ;; use unified diff format (-u). | |
| (setq vc-diff-switches '("-b" "-B" "-u")) | |
| (setq vc-git-diff-switches nil)) | |
| (use-package auto-package-update | |
| :config | |
| (auto-package-update-at-time "11:30")) | |
| (use-package move-text | |
| :config | |
| (move-text-default-bindings)) | |
| (use-package rainbow-mode | |
| :config | |
| (rainbow-mode)) | |
| (use-package rainbow-delimiters | |
| :hook (prog-mode . rainbow-delimiters-mode)) | |
| (use-package breadcrumb | |
| :hook | |
| (prog-mode . breadcrumb-mode) | |
| (conf-mode . breadcrumb-mode)) | |
| (use-package which-key | |
| :config | |
| (which-key-mode)) | |
| (use-package expand-region | |
| :config | |
| (global-set-key (kbd "C-=") 'er/expand-region)) | |
| (use-package diff-hl | |
| :config | |
| (global-diff-hl-mode) | |
| (diff-hl-margin-mode) | |
| :hook | |
| ('magit-post-refresh . diff-hl-magit-post-refresh)) | |
| ;; Enable Vertico | |
| ;; From: https://github.com/minad/vertico?tab=readme-ov-file#configuration | |
| (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)) | |
| (use-package orderless | |
| :custom | |
| ;; Configure a custom style dispatcher (see the Consult wiki) | |
| ;; (orderless-style-dispatchers '(+orderless-consult-dispatch orderless-affix-dispatch)) | |
| ;; (orderless-component-separator #'orderless-escapable-split-on-space) | |
| (completion-styles '(orderless basic)) | |
| (completion-category-overrides '((file (styles partial-completion)))) | |
| (completion-category-defaults nil) ;; Disable defaults, use our settings | |
| (completion-pcm-leading-wildcard t)) ;; Emacs 31: partial-completion behaves like substring | |
| (use-package marginalia | |
| ;; 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 ace-window | |
| :bind (("M-o" . ace-window))) | |
| (use-package link-hint | |
| :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)) | |
| (use-package mistty-project | |
| :ensure nil | |
| :config | |
| (mistty-project-init-kill-buffer) | |
| (keymap-set project-prefix-map "s" 'mistty-in-project)) ; enable Mistty for C-x p s | |
| (use-package company | |
| :hook (after-init . global-company-mode) | |
| :custom | |
| (company-idle-delay 0.1) | |
| (company-minimum-prefix-length 1) | |
| :bind (:map company-active-map | |
| ("TAB" . company-complete-selection) | |
| ("<tab>" . company-complete-selection) | |
| ("C-n" . company-select-next) | |
| ("C-p" . company-select-previous))) | |
| ;; Enable Eglot | |
| (use-package eglot | |
| :config | |
| (add-to-list 'eglot-server-programs '((graphql-mode) . ("graphql-lsp" "server" "-m" "stream"))) | |
| (add-to-list 'eglot-server-programs '((js-mode js-ts-mode) . ("typescript-language-server" "--stdio"))) | |
| (add-to-list 'eglot-server-programs '((kotlin-mode kotlin-ts-mode) . ("kotlin-language-server"))) | |
| (add-to-list 'eglot-server-programs '((lua-mode) . ("lua-language-server"))) | |
| (add-to-list 'eglot-server-programs '((sh-mode bash-ts-mode) . ("bash-language-server" "start"))) | |
| ;; Eglot uses the built-in project package to identify the LSP workspace for a newly-opened buffer. | |
| ;; Link: https://go.dev/gopls/editor/emacs#configuring-project-for-go-modules-in-emacs | |
| (defun my/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 #'my/project-find-go-module) | |
| ;; end | |
| :hook | |
| (bash-ts-mode . eglot-ensure) | |
| (go-ts-mode . eglot-ensure) | |
| (graphql-mode . eglot-ensure) | |
| (js-mode . eglot-ensure) | |
| (js-ts-mode . eglot-ensure) | |
| (kotlin-ts-mode . eglot-ensure) | |
| (lua-mode . eglot-ensure) | |
| (python-mode . eglot-ensure) | |
| (python-ts-mode . eglot-ensure) | |
| (ruby-mode . eglot-ensure) | |
| (ruby-ts-mode . eglot-ensure) | |
| (rust-mode . eglot-ensure) | |
| (sh-mode . eglot-ensure) | |
| (before-save . (lambda () | |
| (when (eglot-managed-p) | |
| (eglot-format-buffer -10 t) | |
| (eglot-code-action-organize-imports t)))) | |
| :bind (("C-c e a" . eglot-code-actions) | |
| ("C-c e r" . my/eglot-rename-with-symbol) | |
| ("C-c e o" . eglot-code-action-organize-imports) | |
| ("C-c e i" . eglot-find-implementation) | |
| ;; Flymake | |
| ("C-c e f d" . flymake-show-project-diagnostics) | |
| ("C-c e f p" . flymake-goto-prev-error) | |
| ("C-c e f n" . flymake-goto-next-error)) | |
| :custom-face | |
| (eglot-highlight-symbol-face ((t (:underline t :inherit bold)))) | |
| :custom | |
| (eglot-workspace-configuration | |
| '((:gopls . | |
| ((staticcheck . t) | |
| (buildFlags . ["-tags=integration_test"]) | |
| (matcher . "CaseSensitive") | |
| (completeUnimported . t) | |
| (usePlaceholders . t) | |
| (analyses . ((unusedparams . t) | |
| (shadow . t))) | |
| (hints . ((assignVariableTypes . t) | |
| (compositeLiteralFields . t) | |
| (constantValues . t) | |
| (functionTypeParameters . t) | |
| (parameterNames . t) | |
| (rangeVariableTypes . t)))))))) | |
| ;; end Eglot | |
| (use-package copilot | |
| :vc (:url "https://github.com/copilot-emacs/copilot.el" | |
| :rev :newest | |
| :branch "main") | |
| :bind (:map copilot-completion-map | |
| ("<tab>" . copilot-accept-completion) | |
| ("TAB" . copilot-accept-completion) | |
| ("C-<tab>" . copilot-accept-completion-by-word)) | |
| ;; :hook | |
| ;; (prog-mode . copilot-mode) | |
| ) | |
| (use-package copilot-chat | |
| :bind (:map global-map | |
| ("C-c C-y" . copilot-chat-yank) | |
| ("C-c M-y" . copilot-chat-yank-pop) | |
| ("C-c C-M-y" . (lambda () (interactive) (copilot-chat-yank-pop -1))))) | |
| (use-package gptel | |
| :ensure t | |
| :config | |
| (setq gptel-model 'gpt-5.2) | |
| (setq gptel-backend (gptel-make-gh-copilot "Copilot"))) | |
| (use-package ruby-mode | |
| :config | |
| (defun my/ruby-compile-command () | |
| (set (make-local-variable 'compile-command) | |
| (concat "ruby " buffer-file-name))) | |
| :hook (ruby-mode . my/ruby-compile-command)) | |
| ;; Handles ANSI colors in the compilation buffer | |
| (use-package ansi-color | |
| :hook (compilation-filter . ansi-color-compilation-filter)) | |
| (use-package kubel | |
| :bind ( | |
| (:map kubel-mode-map | |
| ("RET" . kybel-describe-popup) | |
| ("C" . kybel-set-context) | |
| ("N" . kubel-set-namespace) | |
| ("P" . kubel-port-forward-pod) | |
| ("R" . kubel-set-resource) | |
| ("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)))) | |
| (use-package kubectx-mode | |
| :hook (after-init . kubectx-mode)) | |
| (use-package emojify | |
| :custom | |
| (emojify-display-style 'unicode) | |
| (emojify-emoji-styles '(unicode github))) | |
| (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-mode . emojify-mode)) | |
| (use-package yaml-mode | |
| :config | |
| (defun my/kubectx-get-context () | |
| (shell-command-to-string "kubectl config view --minify --output jsonpath='{.contexts[0].name}'")) | |
| (defun my/kubectx-get-namespace () | |
| (shell-command-to-string "kubectl config view --minify --output jsonpath='{...contexts[0].context.namespace}'")) | |
| (defun my/yaml-compile-command () | |
| (set (make-local-variable 'compile-command) | |
| (concat "kubectl apply --context=" (my/kubectx-get-context) " --namespace=" (my/kubectx-get-namespace) " -f " buffer-file-name))) | |
| :hook | |
| (yaml-mode . my/yaml-compile-command) | |
| (yaml-mode . highlight-indent-guides-mode)) | |
| (use-package sqlite-mode-extras | |
| :hook ((sqlite-mode . sqlite-extras-minor-mode))) | |
| (use-package avy | |
| :bind (("M-g M-c" . avy-goto-char-timer) | |
| ("M-g M-g" . avy-goto-line) | |
| ("M-g M-w" . avy-goto-word-1))) | |
| (use-package so-long | |
| :ensure nil | |
| :defer t) | |
| (use-package jsonian | |
| :after so-long | |
| :custom | |
| (jsonian-no-so-long-mode)) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;; -*- lexical-binding: t; -*- | |
| (require 'transient) | |
| (defun kybel--exec (process-name args &optional readonly callback) | |
| "Utility function to run commands in the proper context and namespace. | |
| PROCESS-NAME is an identifier for the process. Default to \"kubel-command\". | |
| ARGS is a ist of arguments. | |
| CALLBACK is a function that will be executed when the command completes. | |
| READONLY If true buffer will be in readonly mode(view-mode)." | |
| (when (equal process-name "") | |
| (setq process-name "kubel-command")) | |
| (let ((buffer-name (format "*kubel-resource:%s:%s:%s*" kubel-context kubel-namespace (string-join args "_"))) | |
| (error-buffer (kubel--process-error-buffer process-name)) | |
| (cmd (append (list kubel-kubectl) args))) | |
| (when (get-buffer buffer-name) | |
| (kill-buffer buffer-name)) | |
| (when (get-buffer error-buffer) | |
| (kill-buffer error-buffer)) | |
| (kubel--log-command process-name cmd) | |
| (make-process :name process-name | |
| :buffer buffer-name | |
| :sentinel (kubel--sentinel callback) | |
| :file-handler t | |
| :stderr (get-buffer-create error-buffer) | |
| :command cmd) | |
| (pop-to-buffer buffer-name) | |
| (if readonly | |
| (with-current-buffer buffer-name | |
| (view-mode))))) | |
| (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 resource) t) | |
| (yaml-mode) | |
| (view-mode) | |
| (goto-char (point-min)))) | |
| ;; kubectl patch application <MYAPP> -p '[{"op": "remove", "path": "/status/synchronizationHash"}]' --type=json | |
| (defun kybel--jab-nais-app () | |
| "Removes the synchronization hash from the resource" | |
| (interactive) | |
| (let* ((resource-name (kubel--get-resource-under-cursor)) | |
| (process-name (format "kubel - %s - %s" kubel-resource resource-name)) | |
| (cmd (list "patch" kubel-resource resource-name "-p '[{\"op\": \"remove\", \"path\": \"/status/synchronizationHash\"}]' --type=json"))) | |
| (message "Command: %s" cmd) | |
| (kubel--exec process-name cmd t))) | |
| (defun kybel-view-secret () | |
| "View the decryptet secret under the cursor." | |
| (interactive) | |
| (let* ((resource (kubel--get-resource-under-cursor)) | |
| (process-name (format "kubel - %s - %s" kubel-resource resource))) | |
| (kybel--exec process-name (list "view-secret" resource "--all") t) | |
| (yaml-mode) | |
| (view-mode) | |
| (goto-char (point-min)))) | |
| (transient-define-prefix kybel-describe-popup () | |
| "Kubel Describe Menu" | |
| ["Actions" | |
| ("RET" "Describe" kybel-describe-resource) | |
| ("e" "Edit" kubel-get-resource-details) | |
| ("j" "Jab" kybel--jab-nais-app :if (lambda () (member kubel-resource '("applications.nais.io")))) | |
| ("w" "View" kybel-view-secret :if (lambda () (member kubel-resource '("secrets"))))]) | |
| ;; Let you list all resources of one kind cross namespaces | |
| (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*")))) | |
| (defun kybel-set-context () | |
| "Set the context." | |
| (interactive) | |
| (let* ((kubel--buffer (get-buffer (kubel--buffer-name))) | |
| (last-default-directory (when kubel--buffer (with-current-buffer kubel--buffer default-directory)))) | |
| (with-current-buffer (clone-buffer) | |
| (setq kubel-context | |
| (completing-read | |
| "Select context: " | |
| (split-string (kubel--exec-to-string (format "%s config view -o jsonpath='{.contexts[*].name}'" kubel-kubectl)) " "))) | |
| (kubel--invalidate-context-caches) | |
| (setq kubel-namespace (shell-command-to-string "kubectl config view --minify --output 'jsonpath={..namespace}'")) | |
| (switch-to-buffer (current-buffer)) | |
| (kubel-refresh last-default-directory)))) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;; -*- lexical-binding: 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) | |
| ;; kubectl patch <RESOURCE> <MYAPP> -p '[{"op": "remove", "path": "/status/synchronizationHash"}]' --type=json | |
| (defun my/jab--get-cluster-resources (resource-type) | |
| "Fetch resources from the cluster based on RESOURCE-TYPE." | |
| (split-string (shell-command-to-string (format "kubectl get %s --ignore-not-found --no-headers --output=name" resource-type)))) | |
| (defun my/jab-nais-app () | |
| "Removes the synchronization hash from the resource" | |
| (interactive) | |
| (let* ((resource-type (completing-read "Resource type: " '("app" "naisjob" "aivenapp"))) | |
| (resources (my/jab--get-cluster-resources resource-type)) | |
| (chosen-resource (completing-read (format "Choose %s: " resource-type) resources)) | |
| (cmd (format "kubectl patch %s -p '[{\"op\": \"remove\", \"path\": \"/status/synchronizationHash\"}]' --type=json --subresource=status" | |
| chosen-resource))) | |
| (message "Command: %s" cmd) | |
| (shell-command cmd))) | |
| ;; Reverse with C-u | |
| (defun my/sort-lines-by-length (reverse beg end) | |
| "Sort lines by length." | |
| (interactive "P\nr") | |
| (save-excursion | |
| (save-restriction | |
| (narrow-to-region beg end) | |
| (goto-char (point-min)) | |
| (let ;; To make `end-of-line' and etc. to ignore fields. | |
| ((inhibit-field-text-motion t)) | |
| (sort-subr reverse 'forward-line 'end-of-line nil nil | |
| (lambda (l1 l2) | |
| (apply #'< (mapcar (lambda (range) (- (cdr range) (car range))) | |
| (list l1 l2))))))))) | |
| (defun my/toggle-final-newline () | |
| "Controls whether Emacs automatically adds a newline at the end of files when saving." | |
| (interactive) | |
| (setq require-final-newline (not require-final-newline))) | |
| (defun my/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) | |
| ;; 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)) | |
| ;; *** Custom Patch Command Definitions For Magit | |
| (defun my/magit-write-patch (write-function &optional arg) | |
| "Write patch of current diff to a temp buffer, then run WRITE-FUNCTION. | |
| This is useful as a backend abstraction for | |
| `my/magit-write-patch-to-buffer' and `my/magit-copy-patch-kill-ring'. | |
| Cribs lots of code from `magit-patch-save'. Inspired by | |
| https://github.com/magit/magit/issues/4462#issuecomment-892358920." | |
| (interactive) | |
| (require 'magit-mode) | |
| (require 'magit-diff) | |
| (unless (derived-mode-p 'magit-diff-mode) | |
| (user-error "Only diff buffers can be saved as patches")) | |
| (let ((rev magit-buffer-range) | |
| (typearg magit-buffer-typearg) | |
| (args magit-buffer-diff-args) | |
| (files magit-buffer-diff-files)) | |
| (cond ((eq magit-patch-save-arguments 'buffer) | |
| (when arg | |
| (setq args nil))) | |
| ((eq (car-safe magit-patch-save-arguments) 'exclude) | |
| (unless arg | |
| (setq args (-difference args (cdr magit-patch-save-arguments))))) | |
| ((not arg) | |
| (setq args magit-patch-save-arguments))) | |
| (with-temp-buffer | |
| (magit-git-insert "diff" rev "-p" typearg args "--" files) | |
| (funcall write-function))) | |
| (magit-refresh)) | |
| (defun my/magit-write-patch-to-buffer (buffer) | |
| "Write patch format of current diff into chosen buffer. | |
| Finishes with chosen buffer displayed. Uses `magit-patch-save' | |
| internally, so inherits its settings." | |
| (interactive (list (ivy-read "Dump/append patch to buffer: " #'internal-complete-buffer | |
| :def "*patch*"))) | |
| (my/magit-write-patch '(lambda () (append-to-buffer buffer (point-min) (point-max)) | |
| (pop-to-buffer buffer)))) | |
| (defun my/magit-copy-patch-kill-ring () | |
| "Copy patch format of current diff into kill ring. | |
| Uses `magit-patch-save' internally, so inherit it's settings." | |
| (interactive) | |
| (my/magit-write-patch '(lambda () (kill-region (point-min) (point-max))))) | |
| (defun my/kill-kubel-buffers () | |
| "Kill all kubel buffers." | |
| (interactive) | |
| (kill-matching-buffers "\*kubel.*" nil 'NO-ASK)) | |
| (defun my/kill-other-buffers () | |
| "Kill all other buffers than the one you are in now." | |
| (interactive) | |
| (mapc 'kill-buffer (delq (current-buffer) (buffer-list)))) | |
| (defun my/eglot-rename-with-symbol () | |
| "Call `eglot-rename' with the symbol at point as default." | |
| (interactive) | |
| (let* ((sym (thing-at-point 'symbol t)) | |
| (new (read-from-minibuffer "New name: " sym))) | |
| (eglot-rename new))) | |
| (defun my/magit-clone-default-directory (url) | |
| "Specify directory based on repo-path" | |
| (cond | |
| ;; navikt repos go to ~/workspace/nav/REPO | |
| ((string-match "navikt/\\([^/]+\\)" url) | |
| (expand-file-name "~/workspace/nav/")) | |
| ;; nais repos also go to ~/workspace/nav/REPO | |
| ((string-match "nais/\\([^/]+\\)" url) | |
| (expand-file-name "~/workspace/nav/")) | |
| ;; all others go to ~/workspace/REPO | |
| ((string-match "\\([^/:]+\\)[:/]\\([^/]+\\)\\([^/]+\\)\\.git$" url) | |
| (expand-file-name "~/workspace/")) | |
| (t | |
| (expand-file-name "~/workspace/")))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment