Skip to content

Latest commit

 

History

History
2402 lines (2006 loc) · 77.9 KB

emacs.org

File metadata and controls

2402 lines (2006 loc) · 77.9 KB

Emacs Configuration

Editor

;;;  -*- lexical-binding: t -*-

(when (eq system-type 'windows-nt)
  (setenv "Home" (getenv "UserProfile")))

(cond ((getenv "EMACS_HOME_DIR")
       (setq default-directory (getenv "EMACS_HOME_DIR")))
      ((eq system-type 'windows-nt)
       (setq default-directory (concat (getenv "UserProfile") "\\")))
      (t
       (setq default-directory "~/")))

(when (getenv "EMACS_HOME_DIR")
  (setenv "EDITOR" "edit"))
(setq locale-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(prefer-coding-system 'utf-8)
(setq-default buffer-file-coding-system 'utf-8-unix)

(setq gc-cons-threshold (* 256 1024 1024)
      read-process-output-max (* 1024 1024))

(run-with-idle-timer 15 t (lambda () (garbage-collect)))

(setq visible-bell nil
      fill-column 80
      make-backup-files nil
      query-replace-highlight t
      search-highlight t
      inhibit-splash-screen t
      indent-tabs-mode nil
      show-paren-delay 0
      mouse-highlight nil
      show-help-function nil)

(delete-selection-mode)
(add-hook 'text-mode-hook #'turn-on-auto-fill)
(global-font-lock-mode t)
(electric-pair-mode 1)
(show-paren-mode 1)

(global-auto-revert-mode 1)
(setq global-auto-revert-non-file-buffers t
      revert-without-query '(".pdf"))

(require 'origami)
(add-hook 'prog-mode-hook #'origami-mode)
(defun yes-or-no-p (arg)
  "An alias for y-or-n-p, because I hate having to type 'yes' or 'no'."
  (y-or-n-p arg))
(require 'undo-tree)
(setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo")))
(global-undo-tree-mode)
(setq mouse-wheel-scroll-amount '(1))
(setq mouse-wheel-progressive-speed nil)

(global-set-key (kbd "<mouse-4>") 'scroll-down-line)
(global-set-key (kbd "<mouse-5>") 'scroll-up-line)

;;scroll window up/down by one line
(global-set-key (kbd "M-n") (kbd "C-u 2 C-v"))
(global-set-key (kbd "M-p") (kbd "C-u 2 M-v"))

Fix mouse when using emacsclient in tty and daemon launches via gui.

(defun my-terminal-config (&optional frame)
  "Establish settings for the current terminal."
  (if (not frame) ;; The initial call.
      (xterm-mouse-mode 1)
    ;; Otherwise called via after-make-frame-functions.
    (if xterm-mouse-mode
        ;; Re-initialise the mode in case of a new terminal.
        (xterm-mouse-mode 1))))

;; Evaluate both now (for non-daemon emacs) and upon frame creation
;; (for new terminals via emacsclient).
(my-terminal-config)
(add-hook 'after-make-frame-functions #'my-terminal-config)

(add-hook 'tty-setup-hook (lambda ()
			    (define-key input-decode-map "\e[1;9A" [M-up])
			    (define-key input-decode-map "\e[1;9B" [M-down])
			    (define-key input-decode-map "\e[1;9C" [M-right])
			    (define-key input-decode-map "\e[1;9D" [M-left])))

(require 'clipetty)
(global-clipetty-mode)
(require 'saveplace)
(save-place-mode 1)

(setq na-save-places-filename ".emacs-places")

(cond ((getenv "EMACS_HOME_DIR")
       (setq save-place-file
	     (concat "/storage/" na-save-places-filename)))
      (t
       (setq save-place-file
	     (concat "~/" na-save-places-filename))))

(run-with-idle-timer (* 30 60) t #'save-place-kill-emacs-hook)

I use syncthing to sync my bookmarks file across machines, following makes sure we always reload the file before use and same immidiatly after a modification. Bookmark file is reload before emacs is killed to ensure it autosaves the latests version back.

(setq bookmark-save-flag 1)

(cond ((getenv "EMACS_HOME_DIR")
       (setq bookmark-default-file "/storage/source/.emacs-bookmarks"))
      ((file-exists-p "~/source/.emacs-bookmarks")
       (setq bookmark-default-file "~/source/.emacs-bookmarks")))

(global-set-key (kbd "C-x r b") (lambda ()
				  (interactive)
				  (when (file-exists-p bookmark-default-file)
				    (bookmark-load bookmark-default-file t))
				  (helm-bookmarks)))

(add-hook 'kill-emacs-hook (lambda ()
			     (when (file-exists-p bookmark-default-file)
			       (bookmark-load bookmark-default-file t))) -100)
(setq password-cache t) ; enable password caching
(setq password-cache-expiry (* 12 3600)) ; for twelfe hours (time in secs)
(defun na-zoom-in ()
  (interactive)
  (set-face-attribute 'default nil :height
                      (+ (face-attribute 'default :height) 10)))

(defun na-zoom-out ()
  (interactive)
  (set-face-attribute 'default nil :height
                      (- (face-attribute 'default :height) 10)))
(when  (not (eq system-type 'windows-nt))
  (autoload 'flyspell-mode "flyspell" "On-the-fly spelling checker." t)

  (add-hook 'message-mode-hook #'turn-on-flyspell)
  (add-hook 'text-mode-hook    #'turn-on-flyspell)
  (add-to-list 'ispell-skip-region-alist '("+begin_src" . "+end_src"))

  (defun turn-on-flyspell ()
    "Force flyspell-mode on.  For use in hooks."
    (interactive)
    (flyspell-mode 1))

  (defun turn-off-flyspell ()
    "Force flyspell-mode off.  For use in hooks."
    (interactive)
    (flyspell-mode 0))

  (add-hook 'yaml-mode-hook 'turn-off-flyspell))
(require 'helm)

(setq helm-M-x-fuzzy-match t
      helm-split-window-in-side-p t
      helm-move-to-line-cycle-in-source t
      helm-buffer-max-length nil)

(setq helm-boring-buffer-regexp-list
      (list
       "\\` "
       "^\\*Process List\\*$"
       "^\\*Dired log\\*$"
       "^\\*copilot events\\*$"
       "^\\*info\\*$"
       "^\\*Man.*\\*$"
       "^\\*tramp.+\\*$"
       "^\\*trace.+SMTP.+\\*$"
       "^\\.todo-do"
       "^\\*scratch\\*$"
       "^\\*git-status\\*$"
       "^\\*git-diff\\*$"
       "^\\*git-commit\\*$"
       "^\\*Git Command Output\\*$"
       "^\\*Org Export/Publishing Help\\*$"
       "^\\*Org-Babel Error Output\\*$"
       "^\\*Org PDF LaTeX Output\\*$"
       "^\\*Org Agenda\\*$"
       "^\\*Calendar\\*$"
       "^\\*Messages\\*$"
       "^\\*Completions\\*$"
       "^\\*Warnings\\*$"
       "^\\*Org Agenda.*\\*$"
       "^\\*Org Help\\*$"
       "^\\*Backtrace\\*$"
       "^\\*Colors\\*$"
       "^TAGS$"
       "^\\*Help\\*$"
       "^\\*Shell Command Output\\*$"
       "^\\*Calculator\\*$"
       "^\\*Calc Trail\\*$"
       "^\\*Compile-Log\\*$"
       "^\\*quelpa-build-checkout\\*$"
       "^\\*helm.*\\*$"
       "^\\*projectile-files-errors\\*$"
       "^\\*EGLOT.*"
       "^\\*lsp-.*"
       "^\\*jdtls.*"
       "^\\*clangd.*"
       "^\\*Flymake.*"
       "^\\*Native-.*"
       "^\\*Async-native-.*"
       "^\\*Async Shell Command.*"
       "^\\*emacs\\*$"
       "^\\*GNU Emacs\\*$"
       "^\\*compilation\\*$"
       "^\\*elfeed-.*"
       "^\\*pylsp.*"
       "^\\*pyls-remote*"
       "^\\*clojure-lsp.*"
       "^\\*LSP Error List*"
       "^\\*lsp session*"
       "^\\*Flycheck Errors*"
       "^\\*xref\\*$"
       "^\\*grep\\*$"
       "^\\*ob-ansible\\*$"
       "^\\*vc-dir\\*$"
       "^\\*vc\\*$"
       "^\\*Bookmark List\\*$"
       "^\\*Buffer List\\*$"
       "^\\*Disabled Command\\*$"
       "^\\*tfmls\\*$"
       "^\\*tfmls::stderr\\*$"
       (rx "*httpd")
       (rx "*ein:log-all")
       (rx "*nrepl-server")
       (rx "cider-error")
       (rx "cider-macroexpansion")
       (rx "*magit-")
       "magit-*"
       (rx "*Ibuffer")
       (rx "*Echo Area")
       (rx "*Minibuf")
       (rx "*quelpa-build-checkout")
       (rx "*quelpa-build-info*")))

;; Fixes helm messing modeline colors.
(add-hook 'helm-minibuffer-set-up-hook
          (lambda ()
            (advice-add #'doom-modeline--active :override (lambda () t))))

(add-hook 'helm-cleanup-hook
          (lambda ()
            (advice-remove #'doom-modeline--active (lambda () t))))
(setq display-buffer-alist
      '(("magit:.*" (display-buffer-same-window))
	("\*grep\*" (display-buffer-same-window))
	("\*cider-repl.*" (display-buffer-same-window))
	("\*ein:.*" (display-buffer-same-window))))
(defun suppress-messages (old-fun &rest args)
  (cl-flet ((silence (&rest args1) (ignore)))
    (advice-add 'message :around #'silence)
    (unwind-protect
        (apply old-fun args)
      (advice-remove 'message #'silence))))
(defun na-recursive-grep (search-term search-path)
  "Recursively search for SEARCH-TERM in SEARCH-PATH."
  (interactive
   (progn
     (unless grep-command
       (grep-compute-defaults))
     (let ((search-term (grep-read-regexp))
           (search-path (expand-file-name
                         (read-directory-name
                          "Directory: " nil default-directory t))))
       (list search-term search-path))))
  (if (vc-root-dir)
      (vc-git-grep search-term "*" search-path)
    (rgrep search-term "*" search-path)))

IBuffer

(setq ibuffer-saved-filter-groups
      (quote (("default"
               ("Notes"
                (or
                 (name . "^passwd.org$")
                 (name . "^notes.org$")
                 (name . "^notes.org_archive$")
                 (name . "^bookmarks.org$")
                 (name . "^bookmarks.org_archive$")
                 (name . "^inbox.org$")
                 (name . "^inbox.org_archive$")
                 (name . "^shopping.org$")
                 (name . "^shopping.org_archive$")))
               ("Documents" (or (mode . pdf-view-mode)
				(mode . mhtml-mode)))
               ("Source" (or
                          (mode . java-mode)
                          (mode . clojure-mode)
			  (mode . clojurec-mode)
			  (mode . clojurescript-mode)
                          (mode . org-mode)
                          (mode . bibtex-mode)
                          (mode . latex-mode)
                          (mode . xml-mode)
                          (mode . nxml-mode)
                          (mode . scheme-mode)
                          (mode . python-mode)
                          (mode . ruby-mode)
                          (mode . shell-script-mode)
                          (mode . sh-mode)
                          (mode . c-mode)
                          (mode . lisp-mode)
                          (mode . cperl-mode)
                          (mode . pixie-mode)
                          (mode . yaml-mode)
                          (mode . asm-mode)
                          (mode . emacs-lisp-mode)
                          (mode . c++-mode)
                          (mode . makefile-bsdmake-mode)
                          (mode . makefile-mode)
                          (mode . makefile-gmake-mode)
                          (mode . css-mode)
                          (mode . js-mode)
			  (mode . sql-mode)
                          (mode . terraform-mode)
                          (mode . dockerfile-mode)
                          (mode . docker-compose-mode)
			  (mode . markdown-mode)
			  (mode . jsonnet-mode)
			  (name . "^\\.gitignore")
			  (name . "^\\Jenkinsfile")
			  (name . "^\\*ein.*")))
	       ("REPL" (or (name . "^\\*cider-.*")
			   (name . "^\\*nrepl-.*")
			   (name . "^\\*jupyter-.*")
			   (mode . inferior-lisp-mode)
                           (mode . inferior-python-mode)
                           (name . "^*monroe.*")))
               ("Terminal" (or (mode . term-mode)
			       (name . "^*chatgpt.*")
                               (name . "^*eshell.*")
			       (name . "^*ssh.*")
                               (name . "^\\*offlineimap\\*$")
			       (name . "^*Async Shell.*")))
               ("Dired" (or (mode . dired-mode)
                            (mode . sr-mode)))
               ("Magit" (or (name . "^\\*magit.*\\*$")
                            (mode . magit-status-mode)
                            (mode . magit-diff-mode)
                            (mode . magit-process-mode)
                            (mode . magit-stash-mode)
                            (mode . magit-revision-mode)
                            (mode . magit-log-mode)
			    (mode . magit-refs-mode)))
	       ("Gnus" (or (name . "^\\*Group.*\\*$")
			   (name . "^\\*Summary.*\\*$")
			   (name . "^\\*Article.*\\*$")
			   (name . "^\\.newsrc-dribble")))
               ("Emacs" (or
                         (name . "^\\*Process List\\*$")
                         (name . "^\\*Dired log\\*$")
                         (name . "^\\*info\\*$")
                         (name . "^\\*Man.*\\*$")
                         (name . "^\\*tramp.+\\*$")
                         (name . "^\\*trace.+SMTP.+\\*$")
                         (name . "^\\.todo-do")
                         (name . "^\\*scratch\\*$")
                         (name . "^\\*git-status\\*$")
                         (name . "^\\*git-diff\\*$")
                         (name . "^\\*git-commit\\*$")
                         (name . "^\\*Git Command Output\\*$")
                         (name . "^\\*Org Export/Publishing Help\\*$")
                         (name . "^\\*Org-Babel Error Output\\*$")
                         (name . "^\\*Org PDF LaTeX Output\\*$")
                         (name . "^\\*Org Agenda\\*$")
                         (name . "^\\*Calendar\\*$")
                         (name . "^\\*Messages\\*$")
                         (name . "^\\*Completions\\*$")
                         (name . "^\\*Warnings\\*$")
                         (name . "^\\*Org Agenda.*\\*$")
                         (name . "^\\*Org Help\\*$")
                         (name . "^\\*Backtrace\\*$")
			 (name . "^\\*Colors\\*$")
                         (name . "^TAGS$")
                         (name . "^\\*Help\\*$")
                         (name . "^\\*Shell Command Output\\*$")
                         (name . "^\\*Calculator\\*$")
                         (name . "^\\*Calc Trail\\*$")
                         (name . "^\\*Compile-Log\\*$")
                         (name . "^\\*quelpa-build-checkout\\*$")
			 (name . "^\\*quelpa-build-info\\*$")
                         (name . "^\\*helm.*\\*$")
			 (name . "^\\*projectile-files-errors\\*$")
			 (name . "^\\*EGLOT.*")
                         (name . "^\\*lsp-.*")
                         (name . "^\\*jdtls.*")
                         (name . "^\\*clangd.*")
                         (name . "^\\*Flymake.*")
                         (name . "^\\*Native-.*")
                         (name . "^\\*Async-native-.*")
                         (name . "^\\*emacs\\*$")
                         (name . "^\\*GNU Emacs\\*$")
                         (name . "^\\*compilation\\*$")
                         (name . "^\\*elfeed-.*")
                         (name . "^\\*pylsp.*")
			 (name . "^\\*pyls-remote*")
			 (name . "^\\*clojure-lsp.*")
			 (name . "^\\*LSP Error List*")
			 (name . "^\\*lsp session*")
			 (name . "^\\*Flycheck Errors*")
			 (name . "^\\*xref\\*$")
			 (name . "^\\*grep\\*$")
			 (name . "^\\*ob-ansible\\*$")
			 (name . "^\\*vc-dir\\*$")
			 (name . "^\\*vc\\*$")
			 (name . "^\\*Diff\\*$")
			 (name . "^\\*httpd\\*$")
			 (name . "^\\*Bookmark List\\*$")
			 (name . "^\\*Buffer List\\*$")
			 (name . "^\\*Disabled Command\\*$")
			 (name . "^\\*copilot events\\*$")
			 (name . "^\\*kernel-notebook-*")))))))

(setq ibuffer-show-empty-filter-groups nil
      ibuffer-expert t
      ibuffer-display-summary nil)

(add-hook 'ibuffer-mode-hook
          (lambda ()
	    (ibuffer-auto-mode 1)
            (ibuffer-switch-to-saved-filter-groups "default")
	    (setq ibuffer-hidden-filter-groups (list "Terminal"
						     "Dired"
						     "Magit"
						     "Emacs"))
	    (ibuffer-update nil t)))

(setq ibuffer-formats '((mark modified read-only " "
                              (name 30 30 :left :elide)
                              " "
                              (mode 16 16 :left :elide)
                              " " filename-and-process)
                        (mark " "
                              (name 16 -1)
                              " " filename)))

persp-mode

(setq persp-keymap-prefix (kbd "C-c w"))

(require 'persp-mode)

(setq persp-auto-resume-time -1 ;; No autoload buffers
      persp-set-last-persp-for-new-frames nil
      persp-reset-windows-on-nil-window-conf t
      persp-autokill-buffer-on-remove t
      persp-add-buffer-on-after-change-major-mode t
      persp-kill-foreign-buffer-behaviour 'kill)

(defun switch-all-other-frames-to-nil-perspective ()
  "Switch all other frames to nil perspective, except the current frame."
  (interactive)
  (let ((current-frame (selected-frame)))
    (dolist (frame (frame-list))
      (unless (eq frame current-frame)
        (persp-frame-switch persp-nil-name frame)))))

(defun na-persp-frame-switch (name)
  "Switch all other frames to nil perspective, then switch the current frame perspective to NAME."
  (interactive (list (persp-read-persp "Switch to perspective")))
  (switch-all-other-frames-to-nil-perspective)
  (persp-frame-switch name))

(define-key persp-key-map (kbd "s") #'na-persp-frame-switch)

(persp-mode 1)

Terminal

Path

(if (eq system-type 'windows-nt)
    (progn
      (setenv "PATH"
              (concat
               "C:\\Program Files\\CMake\\bin;"
               "C:\\MinGW\\bin;"
	       (concat (getenv "HOME") "\\AppData\\Local\\Google\\Cloud SDK\\google-cloud-sdk\\bin;")
	       (concat (getenv "HOME") ";")
	       (concat (getenv "HOME") "\\Documents;")
	       (concat (getenv "HOME") "\\Documents\\gzip\\bin;")
	       (concat (getenv "HOME") "\\AppData\\Roaming\\Python\\Python36\\Scripts;")
	       (concat (getenv "HOME") "\\AppData\\Roaming\\Python\\Python39\\Scripts;")
	       "C:\\Arduino;"
               "C:\\Program Files\\Arduino;"
               (getenv "PATH")))
      (setenv "C_INCLUDE_PATH" "C:\\MinGW\\include")
      (setenv "CPLUS_INCLUDE_PATH" "C:\\MinGW\\include"))
  (setenv "PATH"
          (concat
	   "/opt/homebrew/opt/[email protected]/libexec/bin:"
	   "/opt/homebrew/opt/[email protected]/Frameworks/Python.framework/Versions/3.9/bin:"
           "/usr/local/bin:"
	   "/opt/homebrew/bin/:"
	   "/opt/homebrew/opt/coreutils/libexec/gnubin:"
	   "/opt/homebrew/opt/openjdk/bin:"
           (concat (getenv "HOME") "/.bin:")
           (concat (getenv "HOME") "/.local/bin:")
	   (concat (getenv "HOME") "/.emacs.build/src:")
	   (concat (getenv "HOME") "/.emacs.build/lib-src:")
           (concat (getenv "HOME") "/.git-annex.linux:")
           (concat (getenv "HOME") "/.rclone:")
	   (getenv "PATH") ":"
	   "/opt/homebrew/Caskroom/miniconda/base/envs/skypilot/bin:")))

(if (eq system-type 'windows-nt)
    (setq exec-path (split-string (getenv "PATH") ";"))
  (setq exec-path (split-string (getenv "PATH") ":")))

(setenv "PAGER" "cat")
;; (setenv "DISPLAY" ":0")

EShell

(require 'eshell)
(require 'em-alias)
(require 'em-tramp) ; to load eshell’s sudo

(setq eshell-hist-ignoredups t
      eshell-ls-initial-args '("-a")              ; list of args to pass to ls (default = nil)
      eshell-prefer-lisp-functions t              ; prefer built-in eshell commands to external ones
      eshell-visual-commands '("htop" "ssh" "aider")
      eshell-prompt-regexp (rx bol "\u03BB" space)
      eshell-banner-message ""
      eshell-cmpl-cycle-completions nil
      eshell-scroll-to-bottom-on-input 'all
      eshell-destroy-buffer-when-process-dies t)

(add-hook 'eshell-mode-hook
          (lambda ()
	    (company-mode -1)
            (define-key eshell-mode-map (kbd "<up>") #'eshell-previous-input)
            (define-key eshell-mode-map (kbd "<down>") #'eshell-next-input)))

(defun eshell-rename-buffer ()
  "Rename eshell buffer based on current directory, preserving buffer index."
  (when (eq major-mode 'eshell-mode)
    (let* ((current-dir (abbreviate-file-name (eshell/pwd)))
	   (base-name "*eshell*")
           (new-name (concat base-name " " current-dir)))
      (rename-buffer new-name t))))

(add-hook 'eshell-after-prompt-hook #'eshell-rename-buffer)

Prompt

(defun na-shell-git-branch (pwd)
  (interactive)
  (if (and (eshell-search-path "git")
           (locate-dominating-file pwd ".git"))
      (concat " \u2014 " (magit-get-current-branch))
    ""))

(defun fish-path (path max-len)
  "Return a potentially trimmed-down version of the directory PATH, replacing
parent directories with their initial characters to try to get the character
length of PATH (sans directory slashes) down to MAX-LEN."
  (let* ((components (split-string (abbreviate-file-name path) "/"))
         (len (+ (1- (length components))
                 (reduce '+ components :key 'length)))
         (str ""))
    (while (and (> len max-len)
                (cdr components))
      (setq str (concat str
                        (cond ((= 0 (length (car components))) "/")
                              ((= 1 (length (car components)))
                               (concat (car components) "/"))
                              (t
                               (if (string= "."
                                            (string (elt (car components) 0)))
                                   (concat (substring (car components) 0 2)
                                           "/")
                                 (string (elt (car components) 0) ?/)))))
            len (- len (1- (length (car components))))
            components (cdr components)))
    (concat str (reduce (lambda (a b) (concat a "/" b)) components))))

(setq eshell-prompt-function
      (lambda ()
        (concat
         (propertize (format-time-string "%H:%M" (current-time)) 'face `(:foreground "Grey50"))
         (propertize " \u2014 " 'face `(:foreground "Grey30"))
         (propertize  (fish-path (eshell/pwd) 40) 'face `(:foreground "Grey50"))
         (propertize (na-shell-git-branch (eshell/pwd)) 'face `(:foreground "Grey50"))
         (propertize "\n" 'face `(:foreground "Grey30"))
         (propertize (if (= (user-uid) 0) "# " "\u03BB ") 'face `(:foreground "#7f7dca")))))

Aliases

(eshell/alias "cls" "clear")
(eshell/alias "df" "df -h")
(eshell/alias "ps-grep" "ps ax | grep -i $1")
(eshell/alias "sudo" "eshell/sudo $*")
(eshell/alias "docker" "*docker $*")
(eshell/alias "docker-compose" "*docker-compose $*")
(eshell/alias "chmod" "*chmod $*")

;; mirror host /folder/
(eshell/alias "mirror" "rsync -avuzL -e ssh \"$1\" \"$2\" --delete")
(eshell/alias "rcp" "rsync -rvLK $1 $2")

(eshell/alias "ggc" "git repack -ad; git reflog expire --expire-unreachable=now --all; git gc --prune=now")
(eshell/alias "gd" "magit-diff-unstaged")
(eshell/alias "ga" "git annex  $*")
(eshell/alias "gas" "git annex sync")
(eshell/alias "gag" "git annex get . --not --in here")
(eshell/alias "gac" "git annex add . && git annex sync --content")
(eshell/alias "to-wasabi" "git annex add . && git annex copy . --to wasabi --not --in wasabi && git annex unused && git annex move --unused --to wasabi && git annex sync")

(eshell/alias "x86" "/usr/bin/arch -x86_64 $*")

(eshell/alias "lein-repl" "lein repl :headless :host 0.0.0.0 :port $1")
(eshell/alias "clj-repl" "clojure -Sdeps '{:deps {nrepl/nrepl {:mvn/version \"0.9.0\"} cider/cider-nrepl {:mvn/version \"0.28.5\"}} :aliases {:cider/nrepl {:main-opts [\"-m\" \"nrepl.cmdline\" \"--middleware\" \"[cider.nrepl/cider-middleware]\"]}}}' -M:cider/nrepl -h 0.0.0.0 -p $1")

(eshell/alias "crun" "conda run -n $1 --no-capture-output ${cdr $*}")
(eshell/alias "ddu" "du -h --max-depth=1 | *sort -hr")
(eshell/alias "k" "kubectl $*")
(eshell/alias "sq" "sky queue -s")
(eshell/alias "aider" "/opt/aider/bin/aider --dark-mode --no-auto-commits --no-check-update $*")

Commands

(defun htop ()
  (interactive)
  (eshell-command "*htop"))

(defun reboot ()
  (interactive)
  (eshell-command "docker restart emacsd"))
;;Clear the eshell buffer.
(defun eshell/clear ()
  (let ((eshell-buffer-maximum-lines 0))
    (eshell-truncate-buffer)))

(defalias 'cls 'eshell/clear)
(defun pcomplete/conn ()
  (pcomplete-here* (na-ssh-completions)))

(eshell/alias "conn" "cd /scp:$1:~")
;; nq exec remote file
(defun eshell/rnq (host file &rest options)
  (let ((default-directory (concat "/ssh:" host ":~")))
    (eshell/echo
     (shell-command-to-string
      (concat "nq " file " "
	      (string-join
	       (mapcar 'prin1-to-string options) " "))))))

(defun eshell/rkill (host pid)
  (let ((default-directory (concat "/ssh:" host ":~")))
    (eshell/echo
     (shell-command-to-string (concat "kill -9 " (number-to-string pid))))))

eshell-exec-visual is not tramp-aware. Let’s make it tramp-aware for SSH at least,

;; https://gist.github.com/ralt/a36288cd748ce185b26237e6b85b27bb
(require 'em-term)

(defun eshell-exec-visual (&rest args)
  "Run the specified PROGRAM in a terminal emulation buffer.
 ARGS are passed to the program.  At the moment, no piping of input is
 allowed."
  (let* (eshell-interpreter-alist
	 (original-args args)
	 (interp (eshell-find-interpreter (car args) (cdr args)))
	 (in-ssh-tramp (and (tramp-tramp-file-p default-directory)
			    (equal (tramp-file-name-method
				    (tramp-dissect-file-name default-directory))
				   "ssh")))
	 (program (if in-ssh-tramp
		      "ssh"
		    (car interp)))
	 (args (if in-ssh-tramp
		   (let ((dir-name (tramp-dissect-file-name default-directory)))
		     (eshell-flatten-list
		      (list
		       "-t"
		       (tramp-file-name-host dir-name)
		       (format
			;;"export TERM=xterm-256color; cd %s; exec %s"
			"cd %s; exec %s"
			(tramp-file-name-localname dir-name)
			(string-join
			 (append
			  (list (tramp-file-name-localname (tramp-dissect-file-name (car interp))))
			  (cdr args))
			 " ")))))
		 (eshell-flatten-list
		  (eshell-stringify-list (append (cdr interp)
						 (cdr args))))))
	 (term-buf
	  (generate-new-buffer
	   (concat "*"
		   (if in-ssh-tramp
		       (format "%s %s" default-directory (string-join original-args " "))
		     (file-name-nondirectory program))
		   "*")))
	 (eshell-buf (current-buffer)))
    (save-current-buffer
      (switch-to-buffer term-buf)
      (term-mode)
      (set (make-local-variable 'term-term-name) eshell-term-name)
      (make-local-variable 'eshell-parent-buffer)
      (setq eshell-parent-buffer eshell-buf)
      (term-exec term-buf program program nil args)
      (let ((proc (get-buffer-process term-buf)))
	(if (and proc (eq 'run (process-status proc)))
	    (set-process-sentinel proc 'eshell-term-sentinel)
	  (error "Failed to invoke visual command")))
      (term-char-mode)
      (if eshell-escape-control-x
	  (term-set-escape-char ?\C-x))))
  nil)
(defconst pcmpl-git-commands
  '("add" "bisect" "branch" "checkout" "clone"
    "commit" "diff" "fetch" "grep"
    "init" "log" "merge" "mv" "pull" "push" "rebase"
    "reset" "rm" "show" "status" "tag" )
  "List of `git' commands.")

(defvar pcmpl-git-ref-list-cmd "git for-each-ref refs/ --format='%(refname)'"
  "The `git' command to run to get a list of refs.")

(defun pcmpl-git-get-refs (type)
  "Return a list of `git' refs filtered by TYPE."
  (with-temp-buffer
    (insert (shell-command-to-string pcmpl-git-ref-list-cmd))
    (goto-char (point-min))
    (let ((ref-list))
      (while (re-search-forward (concat "^refs/" type "/\\(.+\\)$") nil t)
        (add-to-list 'ref-list (match-string 1)))
      ref-list)))

(defun pcomplete/git ()
  "Completion for `git'."
  ;; Completion for the command argument.
  (pcomplete-here* pcmpl-git-commands)
  ;; complete files/dirs forever if the command is `add' or `rm'
  (cond
   ((pcomplete-match (regexp-opt '("add" "rm")) 1)
    (while (pcomplete-here (pcomplete-entries))))
   ;; provide branch completion for the command `checkout'.
   ((pcomplete-match "checkout" 1)
    (pcomplete-here* (pcmpl-git-get-refs "heads")))))

Term

VTerm

(unless (eq system-type 'windows-nt)
  (when (package-installed-p 'vterm)
    (require 'vterm)
    (setq vterm-shell "/bin/bash"
	  vterm-timer-delay 0.01)

    (quelpa '(eshell-vterm
              :fetcher github
	      :repo "iostapyshyn/eshell-vterm"
	      :files ("eshell-vterm.el")))

    (use-package eshell-vterm
      :demand t
      :after eshell
      :config
      (eshell-vterm-mode))))

Term

(setq term-term-name "eterm-color")

(require 'multi-term)
(setq multi-term-program "/bin/bash")

Misc

(defun na-new-term(term-or-shell)
  "Open a new instance of eshell."
  (interactive "P")
  (if term-or-shell
      (if (package-installed-p 'vterm)
	  (vterm t)
	(multi-term))
    (eshell 'N)))
 (setq async-shell-command-display-buffer t
	async-shell-command-buffer 'new-buffer)

 (add-to-list 'display-buffer-alist
	       (cons "\\*Async Shell Command\\*.*" (cons #'display-buffer-no-window nil)))

Popper

(use-package popper
  :ensure t ; or :straight t
  :bind (("M-q"   . popper-toggle-latest)
         ("M-\\"   . popper-cycle)
         ("C-M-\\" . popper-toggle-type))
  :init
  (setq popper-reference-buffers
        '("^\\*eshell.*\\*$" eshell-mode
	  "^*cider-repl.*"
	  "^\\*term.*\\*$" term-mode
	  "^*jupyter-.*"
	  inferior-python-mode
	  inferior-lisp-mode
          compilation-mode))

  (when (package-installed-p 'vterm)
    (push "^\\*vterm\\*.*" popper-reference-buffers)
    (push 'vterm-mode popper-reference-buffers))

  (setq popper-display-function
	(lambda (b a)
	  (display-buffer-same-window b a)))

  (popper-mode +1)
  (popper-echo-mode +1))

Languages

Will bounce between matching parens just like % in vi

(defun na-bounce-sexp ()
  (interactive)
  (let ((prev-char (char-to-string (preceding-char)))
        (next-char (char-to-string (following-char))))
    (cond ((string-match "[[{(<]" next-char) (forward-sexp 1))
          ((string-match "[\]})>]" prev-char) (backward-sexp 1))
          (t (error "%s" "Not on a paren, brace, or bracket")))))
(use-package hl-todo
  :hook (prog-mode . hl-todo-mode)
  :config
  (setq hl-todo-highlight-punctuation ":"
        hl-todo-keyword-faces
        `(("TODO"       warning bold)
          ("FIXME"      error bold)
          ("HACK"       font-lock-constant-face bold)
          ("REVIEW"     font-lock-keyword-face bold)
          ("NOTE"       success bold)
          ("DEPRECATED" font-lock-doc-face bold))))

Clojure

(require 'clojure-mode)
(require 'clojure-mode-extra-font-locking)

(setq nrepl-use-ssh-fallback-for-remote-hosts t
      cider-use-tooltips nil
      cider-eldoc-display-for-symbol-at-point nil)

(add-hook 'cider-repl-mode-hook
	  (lambda ()
	    (define-key cider-repl-mode-map (kbd "C-c C-o") 'cider-repl-clear-buffer)))

C/C++

(add-to-list 'auto-mode-alist '("[.]pde$" . c++-mode))
(add-to-list 'auto-mode-alist '("[.]ino$" . c++-mode))
(add-to-list 'auto-mode-alist '("[.]h$" . c++-mode))
(add-to-list 'auto-mode-alist '("[.]cpp$" . c++-mode))

Python

(setenv "PYTHONDONTWRITEBYTECODE" "1")
(setenv "PYTHONIOENCODING" "utf8")
(setenv "TF_CPP_MIN_LOG_LEVEL" "2")
(setenv "AUTOGRAPH_VERBOSITY" "1")
(setenv "GIT_PYTHON_REFRESH" "quite")

(require 'python)

(setq python-shell-interpreter "python3"
      python-interpreter "python3"
      python-indent-guess-indent-offset-verbose nil)

(when (file-exists-p "/opt/conda")
  (setq conda-anaconda-home "/opt/conda"))

(when (file-exists-p "/opt/homebrew/Caskroom/miniconda")
  (setq conda-anaconda-home "/opt/homebrew/Caskroom/miniconda"))

(when (executable-find "conda")
  (require 'conda)
  (conda-env-initialize-eshell))

Docker

(require 'dockerfile-mode)
(require 'docker-compose-mode)

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

Latex

(setq latex-run-command "pdflatex")

(add-hook 'TeX-after-compilation-finished-functions
          #'TeX-revert-document-buffer)

(defun tex-compile-without-changing-windows ()
  (interactive)
  (save-buffer)
  (save-window-excursion
    (tex-compile
     default-directory
     (concat latex-run-command " " buffer-file-name))))

Skeletons

(setq abbrev-mode t)

(add-hook 'emacs-lisp-mode-hook #'abbrev-mode)
(add-hook 'clojure-mode-hook #'abbrev-mode)
(add-hook 'c++-mode-hook #'abbrev-mode)
(add-hook 'c-mode-hook #'abbrev-mode)
(add-hook 'org-mode-hook #'abbrev-mode)

(define-abbrev-table 'java-mode-abbrev-table '())
(define-abbrev-table 'clojure-mode-abbrev-table '())
(define-abbrev-table 'c++-mode-abbrev-table '())
(define-abbrev-table 'org-mode-abbrev-table '())

Clojure

(define-skeleton skel-clojure-println
  ""
  nil
  "(println "_")")

(define-abbrev clojure-mode-abbrev-table "prt" "" 'skel-clojure-println)

(define-skeleton skel-clojure-defn
  ""
  nil
  "(defn "_" [])")

(define-abbrev clojure-mode-abbrev-table "defn" "" 'skel-clojure-defn)

(define-skeleton skel-clojure-if
  ""
  nil
  "(if ("_"))")

(define-abbrev clojure-mode-abbrev-table "if" "" 'skel-clojure-if )

(define-skeleton skel-clojure-let
  ""
  nil
  "(let ["_"] )")

(define-abbrev clojure-mode-abbrev-table "let" "" 'skel-clojure-let)

(define-skeleton skel-clojure-doseq
  ""
  nil
  "(doseq ["_"] "
  \n > ")")

(define-abbrev clojure-mode-abbrev-table "doseq" "" 'skel-clojure-doseq)

(define-skeleton skel-clojure-do
  ""
  nil
  "(do "_" "
  \n > ")")

(define-abbrev clojure-mode-abbrev-table "do" "" 'skel-clojure-do)

(define-skeleton skel-clojure-reduce
  ""
  nil
  "(reduce (fn[h v] ) "_" ) ")

(define-abbrev clojure-mode-abbrev-table "reduce" "" 'skel-clojure-reduce)

(define-skeleton skel-clojure-try
  ""
  nil
  "(try "_" (catch Exception e (println e)))")

(define-abbrev clojure-mode-abbrev-table "try" "" 'skel-clojure-try)

(define-skeleton skel-clojure-map
  ""
  nil
  "(map #() "_")")

(define-abbrev clojure-mode-abbrev-table "map" "" 'skel-clojure-map)

Java

(define-skeleton skel-java-println
  "Insert a Java println Statement"
  nil
  "System.out.println(" _ " );")

(define-abbrev java-mode-abbrev-table "prt" "" 'skel-java-println )

Company & LSP

(add-hook 'after-init-hook #'global-company-mode)
(setq company-minimum-prefix-length 1)
(global-set-key (kbd "TAB") #'company-indent-or-complete-common)
(require 'yasnippet)
(require 'flycheck)
(require 'lsp-mode)
(require 'lsp-ui)

(define-key lsp-ui-mode-map [remap xref-find-definitions] #'lsp-find-definition)
(define-key lsp-ui-mode-map [remap xref-find-references] #'lsp-find-references)

(setq lsp-log-io nil
      lsp-idle-delay 0.500
      lsp-diagnostics-provider :flycheck
      lsp-headerline-breadcrumb-enable nil
      lsp-ui-sideline-enable t
      lsp-ui-sideline-show-code-actions nil
      lsp-modeline-code-actions-enable nil
      lsp-ui-doc-enable nil
      lsp-signature-auto-activate nil
      lsp-signature-render-documentation nil
      lsp-ui-sideline-show-diagnostics t
      lsp-enable-symbol-highlighting nil
      lsp-eldoc-enable-hover nil)

(setq lsp-keymap-prefix "C-c l")
(define-key lsp-mode-map (kbd "C-c l") lsp-command-map)

(add-hook 'clojure-mode-hook #'lsp-deferred)
(add-hook 'python-mode-hook #'lsp-deferred)

(lsp-register-client
 (make-lsp-client :new-connection (lsp-stdio-connection '("terraform-ls" "serve"))
                  :major-modes '(terraform-mode)
                  :server-id 'terraform-ls))

(add-hook 'terraform-mode-hook #'lsp-deferred)

(lsp-register-client
 (make-lsp-client :new-connection (lsp-tramp-connection "pylsp")
                  :major-modes '(python-mode)
                  :remote? t
                  :server-id 'pyls-remote))

(lsp-register-client
 (make-lsp-client :new-connection (lsp-tramp-connection "clojure-lsp")
                  :major-modes '(clojure-mode)
                  :remote? t
                  :server-id 'clojure-lsp-remote))

(lsp-register-client
 (make-lsp-client :new-connection (lsp-tramp-connection "clojure-lsp")
                  :major-modes '(clojurescript-mode)
                  :remote? t
                  :server-id 'clojurescript-lsp-remote))

(lsp-register-client
 (make-lsp-client :new-connection (lsp-tramp-connection "clojure-lsp")
                  :major-modes '(clojurec-mode)
                  :remote? t
                  :server-id 'clojurescript-lsp-remote))

Fix for - emacs-lsp/lsp-ui#607

(let ((areas '("mode-line"
	       "left-margin"
	       "left-fringe"
	       "right-fringe"
	       "header-line"
	       "vertical-scroll-bar"
	       "vertical-line"
	       "tab-bar"
	       "M-["
	       "nil"))
      loc)
  (while areas
    (setq loc (pop areas))
    (global-set-key (kbd (concat "<" loc "> <mouse-movement>")) #'ignore)
    (define-key clojure-mode-map (kbd (concat "<" loc "> <mouse-movement>")) #'ignore)
    (define-key python-mode-map (kbd (concat "<" loc "> <mouse-movement>")) #'ignore)))

Projectile

(require 'projectile)

(setq projectile-completion-system 'helm
      projectile-switch-project-action #'projectile-dired)

(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)

(projectile-mode +1)

Org-Mode

(require 'org)

(setq org-startup-folded t
      org-adapt-indentation nil
      org-return-follows-link t
      org-startup-with-inline-images t
      org-image-actual-width nil
      org-use-speed-commands t
      org-src-window-setup 'current-window
      org-confirm-babel-evaluate nil
      org-babel-python-command "python3"
      org-hide-leading-stars t
      org-src-fontify-natively t
      org-src-tab-acts-natively t
      org-src-preserve-indentation t
      org-ellipsis ""
      org-link-file-path-type 'relative
      org-capture-bookmark nil
      org-bookmark-names-plist '()
      org-export-babel-evaluate nil)

(add-to-list 'org-link-frame-setup '(file . find-file))

(define-key org-mode-map (kbd "C-c b") #'org-insert-structure-template)

(setq-default prettify-symbols-alist
	      '(("#+NAME:"        . ?☰)
		("#+name:"        . ?☰)
		("#+BEGIN_SRC"    . "λ")
		("#+END_SRC"      . "")
		("#+begin_src"    . "λ")
		("#+end_src"      . "")
		("#+RESULTS:"     . ?☰)
		(":PROPERTIES:"   . ?✎)
		(":header-args+:" . ?✎)
		(":results:"      . ?✎)
		(":end:"          . "")
		(":END:"          . "")))

;;(setq prettify-symbols-unprettify-at-point 'right-edge)
(add-hook 'org-mode-hook 'prettify-symbols-mode)
(setq org-refile-targets '((nil :maxlevel . 9)
			     (org-agenda-files :maxlevel . 9)))
(setq org-outline-path-complete-in-steps nil)         ; Refile in a single go
(setq org-refile-use-outline-path t)                  ; Show full paths for refiling
(require 'org-archive)

(defun kill-org-archive-buffer ()
  (let* ((archive-file (concat (buffer-file-name (current-buffer)) "_archive"))
         (archive-buffer (find-buffer-visiting archive-file)))
    (when archive-buffer
      (kill-buffer archive-buffer))))

(add-hook 'org-archive-hook 'kill-org-archive-buffer)
(quelpa '(org-margin
          :fetcher github
	  :repo "rougier/org-margin"))

(setq org-margin-markers
      (list (cons "\\(#\\+begin_src\\)"
		  (propertize "" 'face '(font-lock-comment-face bold)))
            (cons "\\(#\\+begin_quote\\)"
		  (propertize "" 'face '(font-lock-comment-face bold)))))

(setq org-margin-bookmark (propertize "🔖" 'face '(error bold)))

(add-hook 'org-mode-hook 'org-margin-mode)

Babel

(require 'ob)

(quelpa '(ob-async
          :fetcher github :repo "astahlman/ob-async"))

(require 'ob-async)

(setq ob-async-no-async-languages-alist '("jupyter-python"))

(when  (eq system-type 'windows-nt)
  (setq org-babel-python-command "python.exe"))

;; Run/highlight code using babel in org-mode
(org-babel-do-load-languages
 'org-babel-load-languages
 '((emacs-lisp . t)
   ;; (clojure . t)
   (python . t)
   (sql . t)
   (shell . t)))

(add-hook 'org-babel-after-execute-hook 'org-display-inline-images 'append)
(add-hook 'org-babel-after-execute-hook 'org-save-all-org-buffers 'append)

(setq org-structure-template-alist
      '(("el" . "src emacs-lisp\n")
	("cl" . "src inf-clojure\n")
	("cc" . "src c++\n")
	("sh" . "src sh\n")
	("sq" . "src sql\n")
	("jp" . "src jupyter-python\n")
	("ep" . "src ein-python\n")
	("p" . "src python\n")
	("s" . "src")
	("l" . "export latex")
	("e" . "example")))

(defun org-babel-kill-session ()
  "Kill session for current code block."
  (interactive)
  (unless (org-in-src-block-p)
    (error "You must be in a src-block to run this command"))
  (cl-flet ((always-yes (&rest _) t))
    (cl-letf (((symbol-function 'y-or-n-p) #'always-yes)
            ((symbol-function 'yes-or-no-p) #'always-yes))
    (save-window-excursion
      (org-babel-switch-to-session)
      (kill-buffer)))))

(define-key org-mode-map (kbd "C-c k") 'org-babel-kill-session)
(quelpa '(ob-ansible
          :fetcher github :repo "zweifisch/ob-ansible"))

(require 'ob-ansible)

(setq org-babel-default-header-args:ansible
      '((:results . "silent")))

(add-to-list 'org-src-lang-modes '("ansible" . yaml))

(defun org-babel-execute:ansible (body params)
  (let* ((inventory (org-babel-ref-resolve
                     (cdr (assoc :inventory params))))
         (inventory-file (org-babel-temp-file "ob-ansible-inventory"))
         (module (or (cdr (assoc :module params)) "shell"))
         (hosts (or (cdr (assoc :hosts params)) "all"))
         (forks (cdr (assoc :forks params)))
         (user (or (cdr (assoc :user params)) "root"))
         (oneline (assoc :oneline params))
         (become (assoc :become params))
         (become-user (cdr (assoc :become-user params)))
         (playbook (assoc :playbook params))
         (args (concat " -i " inventory-file
                       (when user (format " -u %s" user))
                       (when become " --become")
                       (when become-user (format " --become-user %s" become-user))
                       (when forks (format " -f %s" forks)))))
    (with-temp-file inventory-file (insert inventory))
    (let* ((default-directory (file-name-directory (buffer-file-name)))
	   (org-babel-temporary-directory default-directory)
	   (cmd
            (if playbook
		(let ((playbook-file (org-babel-temp-file "ob-ansible-playbook")))
                  (with-temp-file playbook-file (insert body))
                  (concat "ansible-playbook" args " " playbook-file " && rm " playbook-file))
              (concat "ansible"
                      (format " \"%s\"" hosts)
                      args
                      " --module-name " module
                      (when oneline " --one-line")
                      (format " --args %s" (shell-quote-argument
                                            (org-babel-ansible--preprocess-inline-src body)))))))
      (async-shell-command cmd "*ob-ansible*")
      'ob-ansible)))
(add-to-list 'org-src-lang-modes '("inf-clojure" . clojure))

(defvar org-babel-default-header-args:inf-clojure
  '((:results . "silent") (:tangle . "yes")))

(defun org-babel-execute:inf-clojure (body params)
  "Evaluate a block of Clojure code with Babel."
  (lisp-eval-string body)
  t)

Latex

(setq org-latex-prefer-user-labels t)

(setq org-latex-pdf-process '("latexmk -pdf -f %f"))

;; \\usepackage[style=authoryear-comp,autocite=footnote]{biblatex}
;; \\addbibresource{/Users/chl/org/references.bib}
(eval-after-load "ox-latex"
  '(add-to-list 'org-latex-classes
                '("tufte-handout"
                  "\\documentclass[nobib]{tufte-handout}
                   \\usepackage{nicefrac}
                   \\usepackage{units}
                   [NO-DEFAULT-PACKAGES]
                   [EXTRA]"
                  ("\\section{%s}" . "\\section*{%s}")
                  ("\\subsection{%s}" . "\\subsection*{%s}")
                  ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
                  ("\\paragraph{%s}" . "\\paragraph*{%s}")
                  ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))))

Agenda

(cond ((file-exists-p "~/org/")
       (setq na-agenda-folder "~/org/"))
      ((file-exists-p "/storage/source/org/")
       (setq na-agenda-folder "/storage/source/org/"))
      ((file-exists-p "~/source/org/")
       (setq na-agenda-folder "~/source/org/"))
      (t
       (setq na-agenda-folder "~/org/")))

(when (file-exists-p na-agenda-folder)
  (add-to-list 'org-agenda-files na-agenda-folder)
  (setq org-default-notes-file
	(concat na-agenda-folder "notes.org")))

(require 'org-agenda)

(setq org-agenda-prefix-format '((agenda  . "  ● %i %?-12t% s")
				 (timeline  . "  % s")
				 (todo  . " %i %-12:c")
				 (tags  . " %i %-12:c")
				 (search . " %i %-12:c")))

(setq org-agenda-custom-commands
      '(("h" "Agenda and Todo"
         ((agenda "" ((org-agenda-span 7)
                      (org-agenda-start-on-weekday nil)
		      (org-deadline-warning-days 0)))
	  (agenda "" ((org-agenda-overriding-header "Deadlines")
		      (org-agenda-entry-types '(:deadline))
		      (org-agenda-show-all-dates nil)
		      (org-agenda-format-date "")))
          (todo "TODO")
          (todo "WAIT")))))

(setq org-capture-templates
      '(("p" "Personal TODO" entry
         (file+headline (lambda () (concat na-agenda-folder "notes.org")) "Personal")
         "* TODO %?\n" :prepend t)
	("b" "Read Later" entry
         (file+headline (lambda () (concat na-agenda-folder "bookmarks.org")) "Read Later")
         "* %?\n" :prepend t)
	("w" "Work TODO" entry
         (file+olp (lambda () (concat na-agenda-folder "notes.org")) "Work")
         "* TODO %?\n" :prepend t)))

(setq org-agenda-window-setup 'current-window
      org-agenda-restore-windows-after-quit t
      org-agenda-show-all-dates t
      org-deadline-warning-days 150
      org-archive-subtree-save-file-p t)

(org-toggle-sticky-agenda)

(defun org-agenda-delete-empty-blocks ()
  "Remove empty agenda blocks.
  A block is identified as empty if there are fewer than 2
  non-empty lines in the block (excluding the line with
  `org-agenda-block-separator' characters)."
  (when org-agenda-compact-blocks
    (user-error "Cannot delete empty compact blocks"))
  (setq buffer-read-only nil)
  (save-excursion
    (goto-char (point-min))
    (let* ((blank-line-re "^\\s-*$")
           (content-line-count (if (looking-at-p blank-line-re) 0 1))
           (start-pos (point))
           (block-re (format "%c\\{10,\\}" org-agenda-block-separator)))
      (while (and (not (eobp)) (forward-line))
        (cond
         ((looking-at-p block-re)
          (when (< content-line-count 2)
            (delete-region start-pos (1+ (point-at-bol))))
          (setq start-pos (point))
          (forward-line)
          (setq content-line-count (if (looking-at-p blank-line-re) 0 1)))
         ((not (looking-at-p blank-line-re))
          (setq content-line-count (1+ content-line-count)))))
      (when (< content-line-count 2)
        (delete-region start-pos (point-max)))
      (goto-char (point-min))
      ;; The above strategy can leave a separator line at the beginning
      ;; of the buffer.
      (when (looking-at-p block-re)
        (delete-region (point) (1+ (point-at-eol))))))
  (setq buffer-read-only t))

(add-hook 'org-agenda-finalize-hook #'org-agenda-delete-empty-blocks)

(let ((window-configuration (make-hash-table :test 'equal)))
  (defun kill-org-agenda ()
    (interactive)
    (kill-this-buffer)
    (set-window-configuration
     (gethash (selected-window) window-configuration nil)))

  (defun jump-to-org-agenda ()
    (interactive)
    (if (string= (buffer-name (current-buffer)) "*Org Agenda(h)*")
	(org-agenda-redo-all)
      (progn
	(puthash (selected-window) (current-window-configuration) window-configuration)
	(delete-other-windows)
	(org-agenda nil "h")
	(org-agenda-redo)
    	(org-agenda-follow-mode)
	(local-set-key [f1] #'kill-org-agenda)
	(local-set-key "q" #'kill-org-agenda)))))

;; (when (file-exists-p na-agenda-folder)
;;   (run-with-idle-timer (* 120 60) t
;; 		       (lambda ()
;; 			 (dolist (f (frame-list))
;; 			   (with-selected-frame f
;; 			     (jump-to-org-agenda))))))

(global-set-key [f1] #'jump-to-org-agenda)

;; Temporary fix, something is overriding this
(setq org-agenda-show-all-dates nil)

QL

(use-package org-ql
  :quelpa (org-ql :fetcher github :repo "alphapapa/org-ql"
		  :files (:defaults (:exclude "helm-org-ql.el"))))

(use-package helm-org-ql
  :quelpa (helm-org-ql :fetcher github :repo "alphapapa/org-ql"
                       :files ("helm-org-ql.el")))

(define-key org-mode-map (kbd "C-c C-j") 'helm-org-ql)

Roam

(cond ((file-exists-p "~/rosetta/")
       (setq na-org-roam-directory "~/rosetta/"))
      ((file-exists-p "/storage/source/rosetta/")
       (setq na-org-roam-directory "/storage/source/rosetta/"))
      ((file-exists-p "~/source/rosetta/")
       (setq na-org-roam-directory "~/source/rosetta/"))
      (t
       (setq na-org-roam-directory "~/rosetta/")))

(when (and (file-exists-p na-org-roam-directory)
	   (or (eq system-type 'gnu/linux)
	       (eq system-type 'darwin)))
  (use-package org-roam
    :ensure t
    :init
    (setq org-roam-v2-ack t)
    :custom
    (org-roam-directory na-org-roam-directory)
    (org-roam-completion-everywhere t)
    :bind (("C-c n l" . org-roam-buffer-toggle)
           ("C-c n f" . org-roam-node-find)
           ("C-c n i" . org-roam-node-insert)
           :map org-mode-map
           ("C-M-i"    . completion-at-point))
    :config
    (org-roam-setup)))

Jupyter

emacs-jupyter

(jupyter-available-kernelspecs t)
;; Extra Setup on OS X

;; Install libtool
;; autoreconf -f -i
;; aclocal && automake --add-missing && autoconf
(when module-file-suffix
  ;;(add-to-list 'native-comp-deferred-compilation-deny-list ".*jupyter.*")

  (require 'jupyter)

  (setq jupyter-long-timeout 30
	jupyter-default-timeout 10
	jupyter-org-auto-connect nil)

  (define-key jupyter-repl-mode-map (kbd "<up>") 'jupyter-repl-history-previous)
  (define-key jupyter-repl-mode-map (kbd "<down>") 'jupyter-repl-history-next)

  (require 'ob-jupyter)

  (org-babel-do-load-languages
   'org-babel-load-languages
   (append org-babel-load-languages
	   '((jupyter . t))))

  (setq org-babel-default-header-args:jupyter-python
	'((:async . "yes")
	  (:session . "/ssh:default-gpu:org-session")
	  (:kernel . "ml")
	  (:results . "raw drawer"))))

(define-key org-mode-map (kbd "C-c l") 'jupyter-org-clear-all-results)

(defun jupyter-server-kernel-list-do-shutdown-aux ()
  (interactive)
  (cl-flet ((always-yes (&rest _) t))
    (cl-letf (((symbol-function 'y-or-n-p) #'always-yes)
              ((symbol-function 'yes-or-no-p) #'always-yes))
      (jupyter-server-kernel-list-do-shutdown))))

(define-key jupyter-server-kernel-list-mode-map (kbd "C-c C-d") 'jupyter-server-kernel-list-do-shutdown-aux)
(define-key jupyter-server-kernel-list-mode-map (kbd "d") 'jupyter-server-kernel-list-do-shutdown-aux)
(define-skeleton skel-org-babel-notebook-header
  ""
  nil
  "#+title: Notebook" \n
  "#+PROPERTY: header-args:jupyter-python :session /ssh:default-gpu:org-session :kernel python" \n
  "#+STARTUP: hidestars\n\n")

emacs-ipython-notebook

(require 'cl)
(require 'ein)
(require 'ein-notebook)

(setq ein:url-or-port '("http://lab-desktop:8181"
			"http://workstation:8181"
			"http://engine:8181"))

(setq ein:output-area-inlined-images t
      ein:worksheet-enable-undo t)

(let ((bg "#1c1c1c"))
  (eval-after-load "ein-cell"
    '(progn
       (set-face-attribute 'ein:codecell-input-area-face nil :background bg)
       (set-face-attribute 'ein:markdowncell-input-area-face nil :background bg)
       (set-face-attribute 'ein:codecell-input-prompt-face nil :background bg)
       (set-face-attribute 'ein:codecell-input-prompt-face nil :foreground "#51afef")
       (set-face-attribute 'ein:markdowncell-input-prompt-face nil :background bg)
       (set-face-attribute 'ein:markdowncell-input-prompt-face nil :foreground "#51afef")
       (set-face-attribute 'ein:cell-output-area nil :background bg)
       (set-face-attribute 'ein:cell-output-area nil :foreground "#5B6268"))))

(with-eval-after-load 'ein-notebooklist
  (define-key ein:notebook-mode-map (kbd "C-c C-c")
    'ein:worksheet-execute-cell))

(defun ein:org-open (link-path)
  "Open IPython notebook specified by LINK-PATH.
This function is to be used for FOLLOW function of
`org-add-link-type'."
  (let ((link (read link-path)))
    (destructuring-bind (&key url-or-port name &allow-other-keys)
        link
      (ein:notebooklist-login 
       url-or-port 
       (apply-partially (lambda (url-or-port* path* &rest args)
                          (ein:notebook-open url-or-port* path*))
                        url-or-port name)))))

(defun ein:org-store-link ()
  "Call `org-store-link-props' when in notebook buffer.
This function is to be used for `org-store-link-functions'.
Examples::
  ipynb:(:url-or-port 8888 :name \"My_Notebook\")
  ipynb:(:url-or-port \"http://notebook-server\" :name \"My_Notebook\")
Note that spaces will be escaped in org files.
As how IPython development team supports multiple directory in
IPython notebook server is unclear, it is not easy to decide the
format for notebook links.  Current approach is to use
S-expression based (rather verbose) serialization, so that
extending link spec without loosing backward compatibility is
easier.  For the examples of link format in general, see Info
node `(org) External links' and Info node `(org) Search options'"
  (ein:and-let* (((ein:worksheet-buffer-p))
                 (notebook (ein:get-notebook))
                 (name (ein:$notebook-notebook-path notebook))
                 (link (list :url-or-port (ein:get-url-or-port)
			     :name name))
                 (description name))
    (org-store-link-props
     :type "ipynb"
     :link (let ((print-length nil)
                 (print-level nil))
	     (format "ipynb:%S" link))
     :description description)))

(eval-after-load "org"
  '(if (fboundp 'org-link-set-parameters)
       (org-link-set-parameters "ipynb"
                                :follow 'ein:org-open
                                :help-echo "Open ipython notebook."
                                :store 'ein:org-store-link)
     (org-add-link-type "ipynb" :follow 'ein:org-open)
     (add-hook 'org-store-link-functions 'ein:org-store-link)))

(org-babel-do-load-languages
 'org-babel-load-languages
 (append org-babel-load-languages
	 '((ein . t))))

(setq org-babel-default-header-args:ein-python
      '((:session . "http://workstation:8181/org.ipynb")
	(:results . "output")))

Common

(defun kernel-app (kernel &optional conn-name)
  (interactive (list (completing-read "Kernel: "
                                      (mapcar (lambda (x)
						(cl-struct-slot-value 'jupyter-kernelspec 'name x))
					      (jupyter-available-kernelspecs t)))))
  (let* ((conn-name (or conn-name "notebook"))
	 (f-conn (concat "/tmp/" conn-name "-" kernel ".json"))
	 (f-conn (expand-file-name f-conn))
	 (default-directory (file-name-directory f-conn))
	 (buffer (concat "*" "kernel-" conn-name "-" kernel "*")))
    (if (file-exists-p f-conn)
	"Kernel Already Exists!"
      (let ((cmd (concat "/bin/python3"
			 " -c \"from jupyter_client.kernelapp import main; main()\""
			 " --kernel=\"" kernel "\""
			 " --KernelManager.connection_file=\"" f-conn "\"")))
	(inhibit-sentinel-messages #'async-shell-command cmd buffer)
	(with-current-buffer (get-buffer buffer)
	  (local-set-key "q" #'bury-buffer))))))

LLM

gptel

(require 'gptel)

(setq litellm-backend
      (gptel-make-openai "LiteLLM"
	:protocol "https"
	:host "llm.computie.net"
	:key (auth-source-pick-first-password :host "llm.computie.net")
	:stream t
	:models '("gpt-4o@azure"
		  "gemini-1.5-pro")))

(setq gptel-backend litellm-backend
      gptel-model "gpt-4o@azure"
      gptel-playback t
      gptel-default-mode 'org-mode
      gptel-display-buffer-action '(pop-to-buffer-same-window))

(add-to-list 'gptel-directives '(jph00 . "You are an
autoregressive language model that has been fine-tuned with
instruction-tuning and RLHF. You carefully provide accurate, factual,
thoughtful, nuanced answers. You are brilliant at reasoning. If you
think there might not be a correct answer, you say so.

Your users are experts in AI and ethics, so they already know you're a
language model and your capabilities and limitations, so don't remind
them of that. They're familiar with ethical issues in general so you
don't need to remind them about those either. Don't be verbose in your
answers, but do provide details and examples where it might help the
explanation. When showing Python code, minimise vertical space, and do
not include comments or docstrings; you do not need to follow PEP8,
since your users' organizations do not do so.

Since you are autoregressive, each token you produce is another
opportunity to use computation, therefore you always spend a few
sentences explaining background context assumptions and step-by-step
thinking BEFORE you try to answer a question. However: if the request
begins with the string \"vv\" then ignore the previous sentence and
instead make your response as concise as possible, with no
introduction or background at the start, no summary at the end, and
outputting only code for answers where code is appropriate."))

(add-to-list 'gptel-directives '(python-jax . "
You are an expert in JAX, Python, NumPy, and Machine Learning.

---

Code Style and Structure

- Write concise, technical Python code with accurate examples.
- Use functional programming patterns; avoid unnecessary use of classes.
- Prefer vectorized operations over explicit loops for performance.
- Use descriptive variable names (e.g., `learning_rate`, `weights`, `gradients`).
- Organize code into functions and modules for clarity and reusability.
- Follow PEP 8 style guidelines for Python code.

JAX Best Practices

- Leverage JAX's functional API for numerical computations.
  - Use `jax.numpy` instead of standard NumPy to ensure compatibility.
- Utilize automatic differentiation with `jax.grad` and `jax.value_and_grad`.
  - Write functions suitable for differentiation (i.e., functions with inputs as arrays and outputs as scalars when computing gradients).
- Apply `jax.jit` for just-in-time compilation to optimize performance.
  - Ensure functions are compatible with JIT (e.g., avoid Python side-effects and unsupported operations).
- Use `jax.vmap` for vectorizing functions over batch dimensions.
  - Replace explicit loops with `vmap` for operations over arrays.
- Avoid in-place mutations; JAX arrays are immutable.
  - Refrain from operations that modify arrays in place.
- Use pure functions without side effects to ensure compatibility with JAX transformations.

Optimization and Performance

- Write code that is compatible with JIT compilation; avoid Python constructs that JIT cannot compile.
  - Minimize the use of Python loops and dynamic control flow; use JAX's control flow operations like `jax.lax.scan`, `jax.lax.cond`, and `jax.lax.fori_loop`.
- Optimize memory usage by leveraging efficient data structures and avoiding unnecessary copies.
- Use appropriate data types (e.g., `float32`) to optimize performance and memory usage.
- Profile code to identify bottlenecks and optimize accordingly.

Error Handling and Validation

- Validate input shapes and data types before computations.
  - Use assertions or raise exceptions for invalid inputs.
- Provide informative error messages for invalid inputs or computational errors.
- Handle exceptions gracefully to prevent crashes during execution.

Testing and Debugging

- Write unit tests for functions using testing frameworks like `pytest`.
  - Ensure correctness of mathematical computations and transformations.
- Use `jax.debug.print` for debugging JIT-compiled functions.
- Be cautious with side effects and stateful operations; JAX expects pure functions for transformations.

Documentation

- Include docstrings for functions and modules following PEP 257 conventions.
  - Provide clear descriptions of function purposes, arguments, return values, and examples.
- Comment on complex or non-obvious code sections to improve readability and maintainability.

Key Conventions

- Naming Conventions
  - Use `snake_case` for variable and function names.
  - Use `UPPERCASE` for constants.
- Function Design
  - Keep functions small and focused on a single task.
  - Avoid global variables; pass parameters explicitly.
- File Structure
  - Organize code into modules and packages logically.
  - Separate utility functions, core algorithms, and application code.

JAX Transformations

- Pure Functions
  - Ensure functions are free of side effects for compatibility with `jit`, `grad`, `vmap`, etc.
- Control Flow
  - Use JAX's control flow operations (`jax.lax.cond`, `jax.lax.scan`) instead of Python control flow in JIT-compiled functions.
- Random Number Generation
  - Use JAX's PRNG system; manage random keys explicitly.
- Parallelism
  - Utilize `jax.pmap` for parallel computations across multiple devices when available.

Performance Tips

- Benchmarking
  - Use tools like `timeit` and JAX's built-in benchmarking utilities.
- Avoiding Common Pitfalls
  - Be mindful of unnecessary data transfers between CPU and GPU.
  - Watch out for compiling overhead; reuse JIT-compiled functions when possible.

Best Practices

- Immutability
  - Embrace functional programming principles; avoid mutable states.
- Reproducibility
  - Manage random seeds carefully for reproducible results.
- Version Control
  - Keep track of library versions (`jax`, `jaxlib`, etc.) to ensure compatibility.

---

Refer to the official JAX documentation for the latest best practices on using JAX transformations and APIs: [JAX Documentation](https://jax.readthedocs.io)
"))

;;(setq gptel-log-level 'debug)
(defun gptel-fix-grammar ()
  "Send selected region to ChatGPT to fix grammar and replace it with the response."
  (interactive)
  (if (use-region-p)
      (let ((region-start (region-beginning))
            (region-end (region-end)))
        (gptel-request
            (buffer-substring-no-properties region-start region-end)
          :system "Correct all grammar and punctuation. Do not change or remove words."
          :buffer (current-buffer)
          :context (cons (set-marker (make-marker) region-start)
                         (set-marker (make-marker) region-end))
          :callback
          (lambda (response info)
            (if (not response)
		(message "gptel-request failed with message: %s" (plist-get info :status))
              (let* ((bounds (plist-get info :context))
                     (beg (car bounds))
                     (end (cdr bounds))
                     (buf (plist-get info :buffer)))
		(with-current-buffer buf
                  (save-excursion
                    (goto-char beg)
                    (kill-region beg end)
                    (insert response)
		    (deactivate-mark))))))))
    (message "No region selected.")))

copilot

(when (executable-find "node")
  (use-package copilot
    :quelpa (copilot :fetcher github :repo "copilot-emacs/copilot.el"
		     :files ("*.el")))

  (when (file-exists-p (concat copilot-install-dir "/bin/copilot-node-server"))
    (setq copilot-indent-offset-warning-disable t)
    (add-hook 'prog-mode-hook 'copilot-mode)
    (add-hook 'yaml-mode-hook 'copilot-mode)

    (define-key copilot-completion-map (kbd "<tab>") 'copilot-accept-completion)
    (define-key copilot-completion-map (kbd "TAB") 'copilot-accept-completion)))

aider

(quelpa '(aider
          :fetcher github
	  :repo "tninja/aider.el"
	  :files ("aider.el")))

(require 'aider)
(setq aider-program "/opt/aider/bin/aider")
(setq aider-args '())

Dired

(require 'dired)

(setq large-file-warning-threshold nil
      ls-lisp-use-insert-directory-program nil
      ls-lisp-dirs-first t
      dired-dwim-target t
      dired-recursive-deletes 'always
      dired-kill-when-opening-new-dired-buffer t
      dired-listing-switches "-l -A -h -v")

(defun dired-sort-newest-first ()
  "Sort dired buffer by modification time, newest first."
  (interactive)
  (dired-sort-other (concat dired-listing-switches " -t -r")))

(quelpa '(emacs-async
          :fetcher github :repo "jwiegley/emacs-async"))

(autoload 'dired-async-mode "dired-async.el" nil t)
(dired-async-mode 1)

(add-hook 'dired-mode-hook
          (lambda ()
            (dired-hide-details-mode)))

(define-key dired-mode-map (kbd "C-w") 'dired-up-directory)

Tramp

(require 'tramp)

(setq tramp-default-method "ssh"
      tramp-ssh-controlmaster-options ""
      remote-file-name-inhibit-cache nil
      remote-file-name-inhibit-locks t
      tramp-verbose 1
      tramp-completion-reread-directory-timeout nil)

(when (eq system-type 'windows-nt)
  ;; Add the '-tt' flag to the login arguments for "ssh" ONLY
  (push '("-tt")
        (cadr (assoc 'tramp-login-args
                     (assoc "ssh" tramp-methods)))))
(defun na-ssh-completions ()
  (mapcar
   (lambda (x)
     (car (cdr x)))
   (seq-filter
    (lambda (x)
      (car (cdr x)))
    (tramp-parse-sconfig "~/.ssh/config"))))

(mapc (lambda (method)
        (tramp-set-completion-function
         method '((tramp-parse-sconfig "~/.ssh/config"))))
      '("rsync" "scp" "sftp" "ssh"))

Git

(setq vc-handled-backends '(Git))

(require 'magit)

(when (or (eq system-type 'gnu/linux)
	  (eq system-type 'darwin))

  (require 'magit-todos)
  (setq magit-todos-exclude-globs '("*.ipynb"))
  (magit-todos-mode 1))

(defalias 'mr 'magit-list-repositories)

(setq git-committer-name "Nurullah Akkaya"
      git-committer-email "[email protected]")

(setq vc-follow-symlinks t
      magit-hide-diffs t
      magit-save-repository-buffers 'dontask)

(remove-hook 'magit-section-highlight-hook 'magit-section-highlight)
(remove-hook 'magit-section-highlight-hook 'magit-diff-highlight)
(defun na-magit-auto-commit-msg ()
  (concat
   "Update:\n"
   (string-join
    (mapcar
     (lambda (f)
       (concat "  " f "\n"))
     (magit-staged-files)))))

(defun na-magit-auto-commit ()
  (interactive)
  (magit-call-git
   "commit" "-m" (na-magit-auto-commit-msg))
  (magit-refresh))

(transient-append-suffix
  'magit-commit "a" '("u" "Auto Commit" na-magit-auto-commit))
(setq magit-repository-directories
      `(("~/org" . 0)
        ("~/source" . 1)
	("~/source/stylitics" . 1)
        ("~/Documents/GitHub/" . 1)
        ("/storage/source" . 1)
	("/storage/source/stylitics" . 1)))

(setq magit-repolist-columns
      '(("Name"    25 magit-repolist-column-ident                  ())
        ("S"        1 magit-repolist-column-flag                   ())
        ("L<U"      3 magit-repolist-column-unpulled-from-upstream ((:right-align t)))
        ("L>U"      3 magit-repolist-column-unpushed-to-upstream   ((:right-align t)))
        ("Path"    99 magit-repolist-column-path                   ())))
(defun na-magit-fetch-all-repositories ()
  "Run `magit-fetch-all' in all repositories returned by `magit-list-repos`."
  (interactive)
  (dolist (repo (magit-list-repos))
    (let ((default-directory repo))
      (magit-call-git "fetch" "--all")))
  (revert-buffer))

(defun na-magit-push-all-repositories ()
  "Run `magit-push' in all repositories returned by `magit-list-repos`."
  (interactive)
  (dolist (repo (magit-list-repos))
    (let ((default-directory repo))
      (let ((current-branch (magit-get-current-branch)))
        (magit-call-git "push" "origin" current-branch))))
  (revert-buffer))

(defun na-magit-auto-commit-multi-repo (&optional _button)
  "Show the status for the repository at point."
  (interactive)
  (--if-let (tabulated-list-get-id)
      (let* ((file (expand-file-name it))
             (default-directory (file-name-directory file)))
        (magit-call-git "add" "-A")
        (magit-call-git "commit" "-m" (na-magit-auto-commit-msg)))
    (user-error "There is no repository at point"))
  (revert-buffer))

(add-hook 'magit-repolist-mode-hook
          (lambda ()
            (define-key magit-repolist-mode-map (kbd "f") #'na-magit-fetch-all-repositories)
            (define-key magit-repolist-mode-map (kbd "p") #'na-magit-push-all-repositories)
            (define-key magit-repolist-mode-map (kbd "c") #'na-magit-auto-commit-multi-repo)))

Research

(when (or (eq system-type 'gnu/linux)
	  (eq system-type 'darwin))
  (use-package pdf-tools
    :config
    (pdf-tools-install :no-query)
    (setq pdf-view-display-size 'fit-page
	  pdf-annot-activate-created-annotations t
	  pdf-view-resize-factor 1.1
	  TeX-view-program-selection '((output-pdf "pdf-tools"))
	  TeX-view-program-list '(("pdf-tools" "TeX-pdf-tools-sync-view")))

    (add-hook 'pdf-view-mode-hook 'pdf-view-midnight-minor-mode)
    (define-key pdf-view-mode-map (kbd "C-s") 'isearch-forward)
    (define-key pdf-view-mode-map (kbd "h") 'pdf-annot-add-highlight-markup-annotation)
    (define-key pdf-view-mode-map (kbd "t") 'pdf-annot-add-text-annotation)
    (define-key pdf-view-mode-map (kbd "D") 'pdf-annot-delete))

  (require 'saveplace-pdf-view)

  (use-package org-noter
    :after (:any org pdf-tools)
    :config
    (setq
     org-noter-always-create-frame nil
     org-noter-hide-other t
     org-noter-notes-search-path (list na-agenda-folder)
     org-noter-auto-save-last-location t)
    :ensure t)

  (use-package org-pdftools
    :hook (org-mode . org-pdftools-setup-link)))

Key Bindings

(setq mac-option-modifier 'super
      mac-command-modifier 'meta)

(global-set-key (kbd "M-x")  #'helm-M-x)
(global-set-key (kbd "C-]")  #'helm-buffers-list)

(global-set-key (kbd "C-x b") #'ibuffer)
(global-set-key (kbd "C-c c") #'org-capture)
(global-set-key (kbd "C-\\")  #'other-window)
(global-set-key (kbd "C-d")   #'na-bounce-sexp)

(global-set-key (kbd "C-M-k")  #'beginning-of-defun)
(global-set-key (kbd "C-M-j")  #'end-of-defun)

(add-hook 'c-mode-hook
          '(lambda ()
	     (define-key c-mode-map (kbd "C-d")  #'na-bounce-sexp)))

(add-hook 'c++-mode-hook
          '(lambda ()
	     (define-key c++-mode-map (kbd "C-d")  #'na-bounce-sexp)))

(add-hook 'chatgpt-shell-mode-hook
          '(lambda ()
	     (define-key chatgpt-shell-mode-map (kbd "C-d")  #'na-bounce-sexp)))

(add-hook 'java-mode-hook
          '(lambda ()
	     (define-key java-mode-map (kbd "C-d")  #'na-bounce-sexp)))

(global-set-key (kbd "C-x t") #'na-new-term)

(with-eval-after-load 'term
  (define-key term-raw-map (kbd "C-c C-c")  #'term-send-raw)
  (define-key term-raw-map (kbd "C-]")      #'helm-buffers-list)
  (define-key term-raw-map (kbd "C-y")      #'term-paste)
  (define-key term-raw-map (kbd "C-\\")     #'other-window)
  (define-key term-raw-map (kbd "M-\\")     #'popper-cycle)
  (define-key term-raw-map (kbd "M-q")      #'popper-toggle-latest))

(with-eval-after-load 'vterm
  (define-key vterm-mode-map (kbd "C-]")      #'helm-buffers-list)
  (define-key vterm-mode-map (kbd "C-y")      #'vterm-yank)
  (define-key vterm-mode-map (kbd "C-\\")     #'other-window)
  (define-key vterm-mode-map (kbd "M-\\")     #'popper-cycle)
  (define-key vterm-mode-map (kbd "M-q")      #'popper-toggle-latest))

(global-set-key "\M-[1;5C" #'forward-word)
(global-set-key "\M-[1;5D" #'backward-word)
(global-set-key "\M-[1;5A" #'backward-paragraph)
(global-set-key "\M-[1;5B" #'forward-paragraph)

(global-set-key (kbd "C-S-<left>")  #'shrink-window-horizontally)
(global-set-key (kbd "C-S-<right>") #'enlarge-window-horizontally)
(global-set-key (kbd "C-S-<down>")  #'shrink-window)
(global-set-key (kbd "C-S-<up>")    #'enlarge-window)

(global-set-key (kbd "C-c <right>") #'origami-open-node)
(global-set-key (kbd "C-c <left>")  #'origami-close-node)
(global-set-key (kbd "C-c <up>")    #'origami-close-all-nodes)
(global-set-key (kbd "C-c <down>")  #'origami-open-all-nodes)

(global-set-key (kbd "C-c j") #'helm-org-ql-agenda-files)

(global-set-key [f2] #'na-elfeed)
(global-set-key [f12] (lambda ()
			(interactive)
			(async-shell-command "QT_XCB_GL_INTEGRATION=none qutebrowser")))

Theme

Layout

(setq frame-title-format (list "Emacs " emacs-version))

(column-number-mode 1)
(blink-cursor-mode 1)
(menu-bar-mode -1)
(scroll-bar-mode -1)
(toggle-scroll-bar -1)
(tool-bar-mode -1)

(defun na-reset-window-size ()
  (interactive)
  (when window-system
    (set-frame-size (selected-frame) 80 25)))

(add-hook 'window-setup-hook 'na-reset-window-size)

(when (getenv "EMACS_HOME_DIR")
  (setq frame-title-format (list "emacsd"))
  (set-face-attribute 'default nil :height 125)
  (blink-cursor-mode))

Font

(when window-system
  (let ((height 110)
	(jetbrains "JetBrains Mono"))
    (when (member jetbrains (font-family-list))
      (set-face-attribute 'default nil :family jetbrains :height height))))

(when (eq system-type 'darwin)
  (set-face-attribute 'default nil :height 150))

(unless (member "all-the-icons" (font-family-list))
  (all-the-icons-install-fonts t))

Theme

(load-theme 'doom-one t)

(set-face-attribute 'show-paren-match nil :foreground "#d65946")
(set-face-attribute 'font-lock-function-name-face nil :foreground "#1d9a79")
(set-face-attribute 'font-lock-builtin-face nil :foreground "#7f7dca")
(set-face-attribute 'font-lock-type-face nil :foreground "#d65946")
(set-face-attribute 'font-lock-constant-face nil :foreground "#ab75c3")
(set-face-attribute 'font-lock-string-face nil :foreground "#6aaf50")
(set-face-attribute 'org-level-2 nil :foreground "#7f7dca")
(set-face-attribute 'font-lock-variable-name-face nil :foreground "#b6b635")
(set-face-attribute 'dired-directory nil :foreground "#7f7dca")
(set-face-attribute 'markdown-header-face nil :foreground "#51afef")


(defun na-fix-background (&optional frame)
  (let ((frame (or frame (setq frame (selected-frame))))
	(bg "#1c1c1c"))
    (set-face-background 'default bg frame)
    (set-face-background 'org-block bg frame)
    (set-face-background 'org-block-begin-line bg frame)
    (set-face-background 'org-block-end-line bg frame)
    (set-face-background 'show-paren-match bg frame)
    (set-face-background 'ansi-color-yellow bg frame)
    (eval-after-load "magit"
      '(progn
	 (remove-hook 'magit-section-highlight-hook 'magit-diff-highlight)
	 (remove-hook 'magit-section-highlight-hook 'magit-section-highlight)
	 (set-face-background 'flycheck-error bg frame)
	 (set-face-background 'smerge-markers bg frame)
	 (set-face-background 'smerge-upper bg frame)
	 (set-face-background 'smerge-lower bg frame)
	 (set-face-background 'magit-diff-lines-heading bg frame)
	 (set-face-foreground 'magit-diff-lines-heading "#727272" frame)
	 (set-face-background 'magit-diff-context bg frame)
	 (set-face-background 'magit-diff-added-highlight bg frame)
	 (set-face-background 'magit-diff-context-highlight bg frame)
	 (set-face-background 'magit-diff-added bg frame)
	 (set-face-background 'magit-diff-removed bg frame)
	 (set-face-background 'magit-diff-hunk-heading bg frame)
	 (set-face-foreground 'magit-diff-hunk-heading "#727272" frame)
	 (set-face-background 'magit-diff-removed-highlight bg frame)))))

(eval-after-load "helm-buffers"
  '(progn
     (set-face-attribute 'helm-buffer-file nil
			 :foreground (face-foreground 'default nil 'default) :background "#1c1c1c")
     (set-face-attribute 'helm-buffer-directory nil
			 :foreground (face-foreground 'font-lock-keyword-face nil 'default) :background "#1c1c1c")))

(add-hook 'after-make-frame-functions 'na-fix-background)
(add-hook 'window-setup-hook 'na-fix-background)

(require 'doom-modeline)
(require 'doom-modeline-segments)

(doom-modeline-def-segment conda-env
  "The current conda environment.  Works with `conda'."
  (when (bound-and-true-p conda-env-current-name)
    (propertize (format " Conda: %s" conda-env-current-name)
                'face (doom-modeline-face)
                'help-echo (format "Conda environment: %s"
                                   conda-env-current-name))))

(setq doom-modeline-icon nil
      doom-modeline-buffer-encoding nil
      doom-modeline-height 15)

(doom-modeline-def-modeline 'main
  ;; left part
  '(bar matches buffer-info buffer-position word-count)
  ;; right part
  ;; misc-info is what is present in global-mode-string
  '(misc-info debug repl lsp minor-modes input-method indent-info buffer-encoding major-mode process vcs conda-env))

(doom-modeline-def-modeline 'dired-line
  '(buffer-info remote-host)
  '(major-mode))

(add-to-list 'doom-modeline-mode-alist '(dired-mode . dired-line))

(set-face-attribute 'mode-line nil :background "#444444" :foreground "#dadada")
(set-face-attribute 'mode-line-inactive nil :background "#262626" :foreground "#767676")

(add-hook 'after-init-hook #'doom-modeline-mode)

Server

(when (getenv "EMACS_HOME_DIR")
  (setq server-socket-dir "/opt/emacsd/server")
  (setq server-name "emacsd")
  (defun server-ensure-safe-dir (dir) "Noop" t))

(unless (server-running-p)
  (server-start))