diff --git a/files/.config/niri/config.kdl b/files/.config/niri/config.kdl index 9e28cbe..dc987b2 100644 --- a/files/.config/niri/config.kdl +++ b/files/.config/niri/config.kdl @@ -274,7 +274,7 @@ layout { spawn-sh-at-startup "emacs --daemon" // To run a shell command (with variables, pipes, etc.), use spawn-sh-at-startup: -spawn-sh-at-startup "dms run" +spawn-sh-at-startup "qs -c dms" spawn-sh-at-startup "wl-paste --watch cliphist store &" spawn-sh-at-startup "nextcloud --background" @@ -382,38 +382,38 @@ binds { // Use spawn-sh to run a shell command. Do this if you need pipes, multiple commands, etc. Mod+Space hotkey-overlay-title="Application Launcher" { - spawn "dms" "ipc" "call" "spotlight" "toggle"; + spawn-sh "qs -c dms ipc call spotlight toggle"; } Mod+V hotkey-overlay-title="Clipboard Manager" { - spawn "dms" "ipc" "call" "clipboard" "toggle"; + spawn-sh "qs -c dms ipc call clipboard toggle"; } Mod+M hotkey-overlay-title="Task Manager" { - spawn "dms" "ipc" "call" "processlist" "toggle"; + spawn-sh "qs -c dms ipc call processlist toggle"; } Super+L hotkey-overlay-title="Lock Screen" { - spawn "dms" "ipc" "call" "lock" "lock"; + spawn-sh "qs -c dms ipc call lock lock"; } Mod+Y hotkey-overlay-title="Browse Wallpapers" { - spawn "dms" "ipc" "call" "dankdash" "wallpaper"; + spawn-sh "qs -c dms ipc call dankdash wallpaper"; } XF86AudioRaiseVolume allow-when-locked=true { - spawn "dms" "ipc" "call" "audio" "increment" "3"; + spawn-sh "qs -c dms ipc call audio increment 3"; } XF86AudioLowerVolume allow-when-locked=true { - spawn "dms" "ipc" "call" "audio" "decrement" "3"; + spawn-sh "qs -c dms ipc call audio decrement 3"; } XF86AudioMute allow-when-locked=true { - spawn "dms" "ipc" "call" "audio" "mute"; + spawn-sh "qs -c dms ipc call audio mute"; } XF86AudioMicMute allow-when-locked=true { - spawn "dms" "ipc" "call" "audio" "micmute"; + spawn-sh "qs -c dms ipc call audio micmute"; } XF86MonBrightnessUp allow-when-locked=true { - spawn "dms" "ipc" "call" "brightness" "increment" "5" ""; + spawn-sh "qs -c dms ipc call brightness increment 5 ''"; } // You can override the default device for e.g. keyboards by adding the device name to the last param XF86MonBrightnessDown allow-when-locked=true { - spawn "dms" "ipc" "call" "brightness" "decrement" "5" ""; + spawn-sh "qs -c dms ipc call brightness decrement 5 ''"; } // Night mode toggle Mod+Shift+N allow-when-locked=true { diff --git a/guix-config/home/emacs/config.el b/guix-config/home/emacs/config.el new file mode 100644 index 0000000..8467fa3 --- /dev/null +++ b/guix-config/home/emacs/config.el @@ -0,0 +1,1107 @@ +(recentf-mode t) + +(use-package golden-ratio + :ensure t + :init + (setq golden-ratio-auto-scale t) + (golden-ratio-mode 1)) + +(defun kylekrein/duplicate-line() + "Duplicate current line and move cursor to it" + (interactive) + (let ((column (- (point) (point-at-bol))) + (line (let ((s (thing-at-point 'line t))) + (if s (string-remove-suffix "\n" s) "")))) + (move-end-of-line 1) + (newline) + (insert line) + (move-beginning-of-line 1) + (forward-char column))) + +(global-set-key [remap list-buffers] 'ibuffer) +(global-set-key (kbd "M-o") 'other-window) +(global-set-key (kbd "C-c o t") 'vterm-toggle) +(global-set-key (kbd "C-c o a") 'org-agenda) +(global-set-key (kbd "C-c o m") 'magit) + +(global-set-key (kbd "C-.") 'kylekrein/duplicate-line) +;;(windmove-default-keybindings) ;; move between windows with S-, S-, S-, S- + +(defun split-and-follow-horizontally () + (interactive) + (split-window-below) + (balance-windows)) + + (defun split-and-follow-vertically () + (interactive) + (split-window-right) + (balance-windows)) + + (use-package emacs + :bind (:map ctl-x-map + ("2" . split-and-follow-horizontally) + ("3" . split-and-follow-vertically)) + :custom + (info-lookup-other-window-flag t) + (help-window-select t "Switch to help buffers automatically")) +;; Auto-select new Info buffer window when it’s created. + (advice-add 'info-lookup :after + (lambda (&rest _) + (when-let (window (get-buffer-window "*info*")) + (select-window window)))) + + ;; Auto-select new window after splitting. Splitting commands almost + ;;,all use `split-window’, so advice the function for auto selection. + (advice-add 'split-window :after + (lambda (&rest _) (select-window (get-lru-window)))) + +(defun git-package (url) + (let* ((pkg-name (file-name-base (directory-file-name url))) + (pkg-sym (intern pkg-name))) + (eval + `(use-package ,pkg-sym + :vc (:url ,url :rev :newest) + :ensure nil)))) + +;;(setq select-enable-primary t) +(defun kylekrein/copy-to-clipboard (text) + (with-temp-buffer + (insert text) + (copy-region-as-kill (point-min) (point-max)) + (clipboard-kill-region (point-min) (point-max)))) + +(defun kylekrein/detect-wsl () + (and (eq system-type 'gnu/linux) + (file-exists-p "/proc/sys/fs/binfmt_misc/WSLInterop"))) + +(defun kylekrein/is-android () + (string-equal system-type "android")) + +(use-package alert + :ensure t + ) + +(require 'alert) + +(defun alert-android-notifications-notify (info) + (unless (kylekrein/is-android) + (error "Android notifications are only supported on Android systems")) + + "Send INFO using android-notifications-notify." + (let ((title (or (plist-get info :title) "Org Alert Reminder")) + (body (or (plist-get info :message) "")) + (urgency (let ((severity (plist-get info :severity))) + (cond ((eq severity 'urgent) 'critical) + ((eq severity 'high) 'critical) + ((eq severity 'moderate) 'normal) + ((eq severity 'low) 'low) + ((eq severity 'trivial) 'low) + (t 'normal)))) + (icon (or (plist-get info :icon) alert-default-icon))) + (android-notifications-notify + :title title + :body body + :urgency urgency + :icon icon + ))) + +(alert-define-style 'android-notifications :title "Android Notifications" + :notifier #'alert-android-notifications-notify + ) + +(use-package alert-toast :ensure t :after alert) + +(setq alert-default-style + (cond + ((kylekrein/is-android) 'android-notifications) + ((kylekrein/detect-wsl) 'toast) + (t 'libnotify))) + +(setq backup-directory-alist '((".*" . "~/.emacs.d/tildafiles"))) + +(use-package diminish :ensure t) + +(defun kylekrein/copy-emoji-to-clipboard() + (interactive) + (let ((emoji (emoji--read-emoji))) + (when emoji + (kylekrein/copy-to-clipboard emoji) + (message "Copied: %s" (current-kill 0 t))))) + +(setq ediff-split-window-function 'split-window-horizontally) +;;(setq ediff-window-setup-function 'ediff-setup-windows-plain) + +(set-face-attribute 'variable-pitch nil + :family "DejaVu Sans";;"ET Bembo" + :height 220 + :weight 'normal) +(set-face-attribute 'default nil + :family "Iosevka" + :height 210 + :weight 'medium) + +(set-face-attribute 'fixed-pitch nil + :family "Iosevka" + :height 210 + :weight 'medium) + + ;; Makes commented text and keywords italics. + ;; This is working in emacsclient but not emacs. + ;; Your font must have an italic face available. + (set-face-attribute 'font-lock-comment-face nil + :slant 'italic) + (set-face-attribute 'font-lock-keyword-face nil + :slant 'italic) + + ;; This sets the default font on all graphical frames created after restarting Emacs. + ;; Does the same thing as 'set-face-attribute default' above, but emacsclient fonts + ;; are not right unless I also add this method of setting the default font. + ;;(add-to-list 'default-frame-alist '(font . "Iosevka Mono-20")) + + ;; Uncomment the following line if line spacing needs adjusting. + (setq-default line-spacing 0.12) + + + (add-hook 'text-mode-hook #'variable-pitch-mode) + ;; Enable variable-pitch-mode in Org + (add-hook 'org-mode-hook #'variable-pitch-mode) + + ;; Ensure code blocks, tables, and special elements remain fixed-pitch + (custom-set-faces + ;; Keep code blocks, src, and tables fixed-pitch (Iosevka) + '(org-block ((t (:inherit fixed-pitch)))) + '(org-block-begin-line ((t (:inherit fixed-pitch)))) + '(org-block-end-line ((t (:inherit fixed-pitch)))) + '(org-table ((t (:inherit fixed-pitch)))) + '(org-code ((t (:inherit fixed-pitch)))) + '(org-verbatim ((t (:inherit fixed-pitch)))) + '(org-meta-line ((t (:inherit fixed-pitch)))) + '(org-checkbox ((t (:inherit fixed-pitch)))) + ) + +(electric-indent-mode -1) ;; Turn off the weird indenting that Emacs does by default. +(electric-pair-mode 1) ;; Turns on automatic parens pairing +;; The following prevents <> from auto-pairing when electric-pair-mode is on. +;; Otherwise, org-tempo is broken when you try to ) and Redo (C-c ) for windows +(setq sentence-end-double-space t) ;; Single space doesn't end a sentence + +(save-place-mode t) ;; Restore cursor place in file + +(unless (or + (equal "Battery status not available" (battery)) + (equal "Power N/A, battery Charging (N/A% load, remaining time N/A)" (battery)) + (equal "Power N/A, battery Discharging (N/A% load, remaining time N/A)" (battery))) + (display-battery-mode 1)) + +(use-package nov :ensure t) +(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode)) + +(use-package magit + :ensure t) + +(use-package doom-modeline + :ensure t + :init (doom-modeline-mode 1) + :config + (setq doom-modeline-height 35 ;; sets modeline height + doom-modeline-bar-width 5 ;; sets right bar width + doom-modeline-persp-name nil ;; adds perspective name to modeline + doom-modeline-time t ;; shows time + doom-modeline-persp-icon nil)) ;; adds folder icon next to persp name + +(use-package rainbow-delimiters + :ensure t + :hook ((emacs-lisp-mode . rainbow-delimiters-mode) + (clojure-mode . rainbow-delimiters-mode))) + +(setq calendar-date-style "european") +(setq calendar-week-start-day 1) + +;;Line truncation +(defun kylekrein/truncate-calendar-hook () + "Turn line truncation on." + (toggle-truncate-lines 1)) + +(add-hook 'calendar-mode-hook #'kylekrein/truncate-calendar-hook) + +;;Current month is the first +(add-hook 'calendar-initial-window-hook #'calendar-scroll-left) + +;;Calendar in org agenda +(setq org-agenda-include-diary t) + +(defadvice revert-buffer (after refresh-org-agenda-on-revert activate) +(if (member (buffer-file-name (current-buffer)) org-agenda-files) + (org-agenda-redo-all t))) + +(org-babel-do-load-languages + 'org-babel-load-languages + '((shell . t) + (C . t) + (python . t))) + +(use-package org + :config + (org-link-set-parameters + "copy" + :follow (lambda (link) (kill-new link)) + :export (lambda (_ desc &rest _) desc))) + +;;;; Better Looking Bullets +(add-hook 'org-mode-hook 'org-indent-mode) +(use-package org-bullets :ensure t) +(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))) + +(custom-set-faces + '(org-level-1 ((t (:inherit outline-1 :height 1.45)))) + '(org-level-2 ((t (:inherit outline-2 :height 1.35)))) + '(org-level-3 ((t (:inherit outline-3 :height 1.30)))) + '(org-level-4 ((t (:inherit outline-4 :height 1.25)))) + '(org-level-5 ((t (:inherit outline-5 :height 1.20)))) + '(org-level-6 ((t (:inherit outline-5 :height 1.15)))) + '(org-level-7 ((t (:inherit outline-5 :height 1.10))))) + +(require 'org-tempo) + +(defun org-update-table-by-name (name) + "Update the named table." + (org-table-map-tables + (lambda () + (let ((table_name (org-element-property :name (org-element-at-point)))) + (if (and table_name (string-match-p name table_name)) + (org-table-recalculate)))))) + +(defun org-update-and-realign-tables () + (interactive) + (org-map-dblocks 'org-update-dblock) + (redisplay) + (org-table-map-tables 'org-table-recalculate) + (org-table-map-tables 'org-table-align)) + +(global-set-key (kbd "C-c n u") 'org-update-and-realign-tables) + +(use-package org-transclusion :ensure t) +(custom-set-faces + '(org-transclusion-fringe + ((t + (:background "green")))) + '(org-transclusion-source-fringe + ((t + (:background "blue"))))) + +(use-package org-roam + :ensure t + :init + (setq org-roam-v2-ack t) + :custom + (org-roam-directory "~/Documents/org") + (org-roam-completion-everywhere t) + (org-roam-capture-templates + '(("d" "default" plain + "%?" + :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+category: ${title}\n") + :unnarrowed t) + ("p" "project" plain "* Goals\n\n%?\n\n* Tasks\n\n** TODO Add initial tasks\n\n* Dates\n\n" + :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+category: ${title}\n#+filetags: Project") + :unnarrowed t)) + ) + (org-roam-dailies-capture-templates + '(("d" "default" entry "* %<%I:%M %p>: %?" + :if-new (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n")))) + :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)) + :bind-keymap + ("C-c n d" . org-roam-dailies-map) + :config + (require 'org-roam-dailies) ;; Ensure the keymap is available + (org-roam-db-autosync-mode) + (org-roam-setup)) + +(defun kylekrein/org-roam-ripgrep () + (interactive) + (require 'consult) + (require 'org-roam) + (let ((consult-ripgrep-command "rg --null --ignore-case --type org --line-buffered --color=always --max-columns=500 --no-heading --line-number . -e ARG OPTS")) + (consult-ripgrep org-roam-directory))) +(global-set-key (kbd "C-c n r") #'kylekrein/org-roam-ripgrep) + +(defun kylekrein/org-roam-capture-inbox () + (interactive) + (org-roam-capture- :node (org-roam-node-create) + :templates '(("i" "inbox" plain "* %?" + :if-new (file+head "Inbox.org" "#+title: Inbox\n#+category: Inbox\n#+filetags: Project"))))) +(global-set-key (kbd "C-c n b") #'kylekrein/org-roam-capture-inbox) + +(defun org-agenda-refresh () + "Refresh all `org-agenda' buffers." + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (when (derived-mode-p 'org-agenda-mode) + (org-agenda-maybe-redo))))) + +(defadvice org-schedule (after refresh-agenda activate) + "Refresh org-agenda." + (org-agenda-refresh)) + +(require 'org-roam-node) +(defun kylekrein/org-roam-filter-by-tag (tag-name) + (lambda (node) + (member tag-name (org-roam-node-tags node)))) + +(defun kylekrein/org-roam-list-notes-by-tag (tag-name) + (mapcar #'org-roam-node-file + (seq-filter + (kylekrein/org-roam-filter-by-tag tag-name) + (org-roam-node-list)))) + +(defun kylekrein/org-roam-refresh-agenda-list () + (interactive) + (setq org-agenda-files (kylekrein/org-roam-list-notes-by-tag "Project"))) + + +(setq org-agenda-files nil + org-roam-node-display-template "${title} ${tags}" + org-agenda-start-on-weekday 1 ;; Week starts on Monday instead of Sunday + ) +;; Build the agenda list the first time for the session +(kylekrein/org-roam-refresh-agenda-list) + +;; Log time a task was set to DONE. +(setq org-log-done (quote time)) + +;; Don't log the time a task was rescheduled or redeadlined. +(setq org-log-redeadline nil) +(setq org-log-reschedule nil) + +;; Prefer rescheduling to future dates and times +(setq org-read-date-prefer-future 'time) + +(use-package emacs + :config + ;; start warning 60 minutes before the appointment + (setq appt-message-warning-time 60) + + ;; warn me every 5 minutes + (setq appt-display-interval 15) + (setq appt-disp-window-function + (lambda (remaining new-time msg) + (alert (format "In %s minutes" remaining) + :title msg + :severity 'moderate + :category 'org-agenda + :id (intern msg)))) + + (advice-add 'appt-check + :before + (lambda (&rest args) + (org-agenda-to-appt t))) + + (appt-activate t)) +(setq alert-fade-time 50) + +(use-package org-upcoming-modeline + :ensure t + :after org + :config + (setq appt-display-mode-line nil) + (org-upcoming-modeline-mode)) + +(use-package rainbow-mode + :ensure t + :hook + ((org-mode prog-mode) . rainbow-mode)) + +(use-package gptel + :ensure t + :bind + ("C-c a c" . gptel) + ("C-c a r" . gptel-rewrite) + ("C-c a s" . gptel-send) + ("C-c a f" . gptel-add-file)) + (setq + gptel-model 'llama3.1 + gptel-backend (gptel-make-ollama "Ollama" + :host "localhost:11434" + :stream t + :models '(llama3.1 qwen2.5-coder:7b)) + gptel-track-media t + gptel-default-mode 'org-mode) +(add-hook 'gptel-post-stream-hook 'gptel-auto-scroll) +(add-hook 'gptel-post-response-functions 'gptel-end-of-response) + +(use-package eshell-syntax-highlighting + :ensure t + :after esh-mode + :config + (eshell-syntax-highlighting-global-mode +1)) + +(unless (kylekrein/is-android) ;;Fails to compile + (use-package vterm + :ensure t + ;;:config +)) + +(unless (kylekrein/is-android) + (use-package vterm-toggle + :ensure t + :after vterm + :config + (setq vterm-toggle-fullscreen-p nil) + (setq vterm-toggle-scope 'project) + (add-to-list 'display-buffer-alist + '((lambda (buffer-or-name _) + (let ((buffer (get-buffer buffer-or-name))) + (with-current-buffer buffer + (or (equal major-mode 'vterm-mode) + (string-prefix-p vterm-buffer-name (buffer-name buffer)))))) + (display-buffer-reuse-window display-buffer-at-bottom) + ;;(display-buffer-reuse-window display-buffer-in-direction) + ;;display-buffer-in-direction/direction/dedicated is added in emacs27 + ;;(direction . bottom) + ;;(dedicated . t) ;dedicated is supported in emacs27 + (reusable-frames . visible) + (window-height . 0.3))))) + +(git-package "https://github.com/darcamo/cmake-integration.git") +(use-package cmake-integration + :commands (cmake-integration-transient) + :custom + (cmake-integration-generator "Ninja") + (cmake-integration-use-separated-compilation-buffer-for-each-target t)) + +(defun is-cmake-project? () + "Determine if the current directory is a CMake project." + (interactive) + (if-let* ((project (project-current)) + (project-root (project-root project)) + (cmakelist-path (expand-file-name "CMakeLists.txt" project-root))) + (file-exists-p cmakelist-path))) + + +(defun cmake-integration-keybindings-mode-turn-on-in-cmake-projects () + "Turn on `cmake-integration-keybindings-mode' in CMake projects." + (when (is-cmake-project?) + (cmake-integration-keybindings-mode 1))) + + +(define-minor-mode cmake-integration-keybindings-mode + "A minor-mode for adding keybindings to compile C++ code using cmake-integration package." + nil + "cmake" + '( + ([f5] . cmake-integration-transient) ;; Open main transient menu + ([M-f9] . cmake-integration-save-and-compile) ;; Ask for the target name and compile it + ([f9] . cmake-integration-save-and-compile-last-target) ;; Recompile the last target + ([C-f9] . cmake-integration-run-ctest) ;; Run CTest + ([f7] . cmake-integration-run-last-target) ;; Run the target (using any previously set command line parameters) + ([S-f7] . kill-compilation) + ([C-f7] . cmake-integration-debug-last-target) ;; Debug the target (using any previously set command line parameters) + ([M-f7] . cmake-integration-run-last-target-with-arguments) ;; Ask for command line parameters to run the target + ([M-f8] . cmake-integration-select-configure-preset) ;; Ask for a preset name and call CMake to configure the project + ([f8] . cmake-integration-cmake-reconfigure) ;; Call CMake to configure the project using the last chosen preset + ) + ) + +(define-globalized-minor-mode global-cmake-integration-keybindings-mode + cmake-integration-keybindings-mode cmake-integration-keybindings-mode-turn-on-in-cmake-projects) + + +(global-cmake-integration-keybindings-mode) + +;; Extend project.el to recognize local projects based on a .project file +(cl-defmethod project-root ((project (head local))) + (cdr project)) + +(defun mu--project-files-in-directory (dir) + "Use `fd' to list files in DIR." + (let* ((default-directory dir) + (localdir (file-local-name (expand-file-name dir))) + (command (format "fd -t f -0 . %s" localdir))) + (project--remote-file-names + (sort (split-string (shell-command-to-string command) "\0" t) + #'string<)))) + +(cl-defmethod project-files ((project (head local)) &optional dirs) + "Override `project-files' to use `fd' in local projects." + (mapcan #'mu--project-files-in-directory + (or dirs (list (project-root project))))) + +(defun mu-project-try-local (dir) + "Determine if DIR is a non-Git project. +DIR must include a .project file to be considered a project." + (let ((root (locate-dominating-file dir ".project"))) + (and root (cons 'local root)))) + +(use-package project + :defer t + :config + (add-to-list 'project-find-functions 'mu-project-try-local) + ) + +(use-package direnv + :ensure t + :config + (direnv-mode)) + +(defun kylekrein/project-enable-direnv-flake () + "Add `use flake` to .envrc and run `direnv allow` in the project root." + (interactive) + (let* ((project (project-current t)) + (root (project-root project)) + (envrc-path (expand-file-name ".envrc" root))) + (unless (file-exists-p envrc-path) + (with-temp-buffer + (insert "use flake\n") + (write-file envrc-path))) + (unless (string-match-p "use flake" (with-temp-buffer + (insert-file-contents envrc-path) + (buffer-string))) + (with-temp-buffer + (insert-file-contents envrc-path) + (goto-char (point-max)) + (insert "\nuse flake\n") + (write-file envrc-path))) + (let ((default-directory root)) + (direnv-allow)) + (message "Added 'use flake' to .envrc and ran direnv allow in %s" root))) + +(use-package nix-ts-mode + :ensure t + :mode "\\.nix\\'" + :hook + (nix-ts-mode . lsp-deferred) ;; So that envrc mode will work + :custom + (lsp-disabled-clients '((nix-ts-mode . nix-nil))) ;; Disable nil so that nixd will be used as lsp-server + :config + (setq lsp-nix-nixd-server-path "nixd" + lsp-nix-nixd-formatting-command [ "alejandra" ] + lsp-nix-nixd-nixpkgs-expr "import { }" + lsp-nix-nixd-nixos-options-expr "(builtins.getFlake \"github:kylekrein/nixos-config\".nixosConfigurations.kylekrein-homepc.options" + lsp-nix-nixd-home-manager-options-expr "(builtins.getFlake \"github:kylekrein/nixos-config\".nixosConfigurations.kylekrein-homepc.options.home-manager.users.type.getSubOptions []")) + +(use-package glsl-mode + :ensure t) + +(add-to-list 'auto-mode-alist '("\\.rml\\'" . html-ts-mode)) +(add-to-list 'auto-mode-alist '("\\.rcss\\'" . css-ts-mode)) + +(add-to-list 'auto-mode-alist '("CMakeLists\\.txt\\'" . cmake-ts-mode)) +(add-to-list 'auto-mode-alist '("\\.cmake\\'" . cmake-ts-mode)) + +(use-package treesit-auto + :ensure t + :demand t + :config + (global-treesit-auto-mode)) + +(use-package eldoc + :init + (global-eldoc-mode)) + + (use-package eglot + :hook (prog-mode . eglot-ensure) + ;;:init + ;;(setq eglot-stay-out-of '(flymake)) + :bind (:map + eglot-mode-map + ("C-c c a" . eglot-code-actions) + ;;("C-c c o" . eglot-code-actions-organize-imports) + ("C-c c r" . eglot-rename) + ("C-c c f" . eglot-format))) + + (use-package flymake + :hook (prog-mode . flymake-mode) + :bind (:map flymake-mode-map + ("C-c ! n" . flymake-goto-next-error) + ("C-c ! p" . flymake-goto-prev-error) + ("C-c ! l" . flymake-show-buffer-diagnostics))) + +(with-eval-after-load 'eglot + (add-to-list 'eglot-server-programs + '((c-ts-mode c++-ts-mode) + . ("clangd" + "-j=8" + "--log=error" + "--malloc-trim" + "--background-index" + "--clang-tidy" + "--cross-file-rename" + "--completion-style=detailed" + "--pch-storage=memory" + "--header-insertion=never" + "--header-insertion-decorators=0"))) + (add-hook 'c-ts-mode-hook #'eglot-ensure) + (add-hook 'c++-ts-mode-hook #'eglot-ensure)) + +(with-eval-after-load 'eglot + (add-to-list 'eglot-server-programs + '(csharp-ts-mode + . ("csharp-ls"))) + (add-hook 'csharp-ts-mode-hook #'eglot-ensure)) + +(with-eval-after-load 'eglot + (add-to-list 'eglot-server-programs + '(python-ts-mode + . ("ty"))) + (add-hook 'python-ts-mode-hook #'eglot-ensure)) + +(use-package nerd-icons + :ensure t + ;; :custom + ;; The Nerd Font you want to use in GUI + ;; "Symbols Nerd Font Mono" is the default and is recommended + ;; but you can use any other Nerd Font if you want + ;; (nerd-icons-font-family "Symbols Nerd Font Mono") + ) + +(use-package nerd-icons-completion + :ensure t + :after marginalia + :config + (nerd-icons-completion-mode) + (add-hook 'marginalia-mode-hook #'nerd-icons-completion-marginalia-setup)) + +(use-package persist-state + :ensure t + :after server + :if server-process + :config + (persist-state-mode)) + +(use-package multiple-cursors +:ensure t +:bind ( +("C-S-c C-S-c" . mc/edit-lines) +("C->" . mc/mark-next-like-this) +("C-<" . mc/mark-previous-like-this) +("C-C C-<" . mc/mark-all-like-this) +("C-\"" . mc/skip-to-next-like-this) +("C-:" . mc/skip-to-previous-like-this) +("C-C C->" . mc/mark-more-like-this-extended) +("C-S-" . mc/add-cursor-on-click) +)) + +(require 'windmove) + +;;;###autoload +(defun buf-move-up () + "Swap the current buffer and the buffer above the split. +If there is no split, ie now window above the current one, an +error is signaled." +;; "Switches between the current buffer, and the buffer above the +;; split, if possible." + (interactive) + (let* ((other-win (windmove-find-other-window 'up)) + (buf-this-buf (window-buffer (selected-window)))) + (if (null other-win) + (error "No window above this one") + ;; swap top with this one + (set-window-buffer (selected-window) (window-buffer other-win)) + ;; move this one to top + (set-window-buffer other-win buf-this-buf) + (select-window other-win)))) + +;;;###autoload +(defun buf-move-down () +"Swap the current buffer and the buffer under the split. +If there is no split, ie now window under the current one, an +error is signaled." + (interactive) + (let* ((other-win (windmove-find-other-window 'down)) + (buf-this-buf (window-buffer (selected-window)))) + (if (or (null other-win) + (string-match "^ \\*Minibuf" (buffer-name (window-buffer other-win)))) + (error "No window under this one") + ;; swap top with this one + (set-window-buffer (selected-window) (window-buffer other-win)) + ;; move this one to top + (set-window-buffer other-win buf-this-buf) + (select-window other-win)))) + +;;;###autoload +(defun buf-move-left () +"Swap the current buffer and the buffer on the left of the split. +If there is no split, ie now window on the left of the current +one, an error is signaled." + (interactive) + (let* ((other-win (windmove-find-other-window 'left)) + (buf-this-buf (window-buffer (selected-window)))) + (if (null other-win) + (error "No left split") + ;; swap top with this one + (set-window-buffer (selected-window) (window-buffer other-win)) + ;; move this one to top + (set-window-buffer other-win buf-this-buf) + (select-window other-win)))) + +;;;###autoload +(defun buf-move-right () +"Swap the current buffer and the buffer on the right of the split. +If there is no split, ie now window on the right of the current +one, an error is signaled." + (interactive) + (let* ((other-win (windmove-find-other-window 'right)) + (buf-this-buf (window-buffer (selected-window)))) + (if (null other-win) + (error "No right split") + ;; swap top with this one + (set-window-buffer (selected-window) (window-buffer other-win)) + ;; move this one to top + (set-window-buffer other-win buf-this-buf) + (select-window other-win)))) + +(use-package windmove + :bind + (("" . windmove-up) + ("" . windmove-down) + ("" . windmove-left) + ("" . windmove-right) + ("" . buf-move-up) + ("" . buf-move-down) + ("" . buf-move-left) + ("" . buf-move-right))) + +(use-package corfu + :ensure t + ;; Optional customizations + :custom + (corfu-cycle t) ;; Enable cycling for `corfu-next/previous' + (corfu-auto t) + (corfu-auto-prefix 2) + (corfu-quit-at-boundary 'separator) + (corfu-echo-documentation 0.25) + (corfu-preselect-first nil) + (corfu-popupinfo-delay '(1.0 . 0.3)) ;;default '(2.0 . 1.0) + ;; (corfu-quit-no-match nil) ;; Never quit, even if there is no match + ;; (corfu-preview-current nil) ;; Disable current candidate preview + ;; (corfu-preselect 'prompt) ;; Preselect the prompt + ;; (corfu-on-exact-match nil) ;; Configure handling of exact matches + + ;; Enable Corfu only for certain modes. See also `global-corfu-modes'. + ;; :hook ((prog-mode . corfu-mode) + ;; (shell-mode . corfu-mode) + ;; (eshell-mode . corfu-mode)) + :bind (:map corfu-map + ("M-SPC" . corfu-insert-separator) + ("RET" . nil) + ("TAB" . corfu-next) + ([tab] . corfu-next) + ("SHIFT-TAB" . corfu-previous) + ([backtab] . corfu-previous) + ("S-" . corfu-insert)) + + ;; Recommended: Enable Corfu globally. This is recommended since Dabbrev can + ;; be used globally (M-/). See also the customization variable + ;; `global-corfu-modes' to exclude certain modes. + :init + (global-corfu-mode) + (corfu-history-mode) + (corfu-popupinfo-mode)) + +;; A few more useful configurations... +(use-package emacs + :custom + ;; TAB cycle if there are only few candidates + ;; (completion-cycle-threshold 3) + + ;; Enable indentation+completion using the TAB key. + ;; `completion-at-point' is often bound to M-TAB. + (tab-always-indent 'complete) + + ;; Emacs 30 and newer: Disable Ispell completion function. + ;; Try `cape-dict' as an alternative. + (text-mode-ispell-word-completion nil) + + ;; Hide commands in M-x which do not apply to the current mode. Corfu + ;; commands are hidden, since they are not used via M-x. This setting is + ;; useful beyond Corfu. + (read-extended-command-predicate #'command-completion-default-include-p)) + +(use-package cape + :ensure t + :defer 10 + :init +(add-to-list 'completion-at-point-functions #'cape-file)) + +;; Enable vertico + (use-package vertico + :ensure t + :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)) + +(vertico-mode t) ;; enable vertico for all buffers + ;; Persist history over Emacs restarts. Vertico sorts by history position. + (use-package savehist + :init + (savehist-mode)) + + ;; A few more useful configurations... + (use-package emacs + :custom + ;; 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) + :init + ;; Add prompt indicator to `completing-read-multiple'. + ;; We display [CRM], e.g., [CRM,] if the separator is a comma. + (defun crm-indicator (args) + (cons (format "[CRM%s] %s" + (replace-regexp-in-string + "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" + crm-separator) + (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)) + +;; Optionally use the `orderless' completion style. +(use-package orderless + :ensure t + :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 flex basic partial-completion)) + + (completion-category-defaults nil) + (completion-category-overrides '((file (styles partial-completion))))) + +;; Example configuration for Consult + (use-package consult + :ensure t + ;; Replace bindings. Lazily loaded by `use-package'. + :bind (;; C-c bindings in `mode-specific-map' + ("C-c M-x" . consult-mode-command) + ("C-c h" . consult-history) + ("C-c k" . consult-kmacro) + ("C-c m" . consult-man) + ("C-c i" . consult-info) + ([remap Info-search] . consult-info) + ;; C-x bindings in `ctl-x-map' + ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command + ("C-x b" . consult-buffer) ;; orig. switch-to-buffer + ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window + ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame + ("C-x t b" . consult-buffer-other-tab) ;; orig. switch-to-buffer-other-tab + ("C-x r b" . consult-bookmark) ;; orig. bookmark-jump + ("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer + ;; Custom M-# bindings for fast register access + ("M-#" . consult-register-load) + ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated) + ("C-M-#" . consult-register) + ;; Other custom bindings + ("M-y" . consult-yank-pop) ;; orig. yank-pop + ;; M-g bindings in `goto-map' + ("M-g e" . consult-compile-error) + ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck + ("M-g g" . consult-goto-line) ;; orig. goto-line + ("M-g M-g" . consult-goto-line) ;; orig. goto-line + ("M-g o" . consult-outline) ;; Alternative: consult-org-heading + ("M-g m" . consult-mark) + ("M-g k" . consult-global-mark) + ("M-g i" . consult-imenu) + ("M-g I" . consult-imenu-multi) + ;; M-s bindings in `search-map' + ("M-s d" . consult-find) ;; Alternative: consult-fd + ("M-s c" . consult-locate) + ("M-s g" . consult-grep) + ("M-s G" . consult-git-grep) + ("M-s r" . consult-ripgrep) + ("M-s l" . consult-line) + ("M-s L" . consult-line-multi) + ("M-s k" . consult-keep-lines) + ("M-s u" . consult-focus-lines) + ;; Isearch integration + ("M-s e" . consult-isearch-history) + :map isearch-mode-map + ("M-e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s l" . consult-line) ;; needed by consult-line to detect isearch + ("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch + ;; Minibuffer history + :map minibuffer-local-map + ("M-s" . consult-history) ;; orig. next-matching-history-element + ("M-r" . consult-history)) ;; orig. previous-matching-history-element + + ;; Enable automatic preview at point in the *Completions* buffer. This is + ;; relevant when you use the default completion UI. + :hook (completion-list-mode . consult-preview-at-point-mode) + + ;; The :init configuration is always executed (Not lazy) + :init + + ;; Tweak the register preview for `consult-register-load', + ;; `consult-register-store' and the built-in commands. This improves the + ;; register formatting, adds thin separator lines, register sorting and hides + ;; the window mode line. + (advice-add #'register-preview :override #'consult-register-window) + (setq register-preview-delay 0.5) + + ;; Use Consult to select xref locations with preview + (setq xref-show-xrefs-function #'consult-xref + xref-show-definitions-function #'consult-xref) + + ;; Configure other variables and modes in the :config section, + ;; after lazily loading the package. + :config + + ;; Optionally configure preview. The default value + ;; is 'any, such that any key triggers the preview. + ;; (setq consult-preview-key 'any) + ;; (setq consult-preview-key "M-.") + ;; (setq consult-preview-key '("S-" "S-")) + ;; For some commands and buffer sources it is useful to configure the + ;; :preview-key on a per-command basis using the `consult-customize' macro. + (consult-customize + consult-theme :preview-key '(:debounce 0.2 any) + consult-ripgrep consult-git-grep consult-grep consult-man + consult-bookmark consult-recent-file consult-xref + consult--source-bookmark consult--source-file-register + consult--source-recent-file consult--source-project-recent-file + ;; :preview-key "M-." + :preview-key '(:debounce 0.4 any)) + + ;; Optionally configure the narrowing key. + ;; Both < and C-+ work reasonably well. + (setq consult-narrow-key "<") ;; "C-+" + + ;; Optionally make narrowing help available in the minibuffer. + ;; You may want to use `embark-prefix-help-command' or which-key instead. + ;; (keymap-set consult-narrow-map (concat consult-narrow-key " ?") #'consult-narrow-help) + ) +(require 'consult) +;;(setq read-file-name-function #'consult-find-file-with-preview) + +;;Previewing files in find-file +(defun consult-find-file-with-preview (prompt &optional dir default mustmatch initial pred) + (interactive) + (let ((default-directory (expand-file-name (or dir default-directory))) + (minibuffer-completing-file-name t)) + (consult--read #'read-file-name-internal :state (consult--file-preview) + :prompt prompt + :initial initial + :require-match mustmatch + :predicate pred))) + +;;Previewing files for project-find-file +(setq project-read-file-name-function #'consult-project-find-file-with-preview) + +(defun consult-project-find-file-with-preview (prompt all-files &optional pred hist _mb) + (let ((prompt (if (and all-files + (file-name-absolute-p (car all-files))) + prompt + ( concat prompt + ( format " in %s" + (consult--fast-abbreviate-file-name default-directory))))) + (minibuffer-completing-file-name t)) + (consult--read (mapcar + (lambda (file) + (file-relative-name file)) + all-files) + :state (consult--file-preview) + :prompt (concat prompt ": ") + :require-match t + :history hist + :category 'file + :predicate pred))) + +;; Enable rich annotations using the Marginalia package +(use-package marginalia + :ensure t + ;; Bind `marginalia-cycle' locally in the minibuffer. To make the binding + ;; available in the *Completions* buffer, add it to the + ;; `completion-list-mode-map'. + :bind (:map minibuffer-local-map + ("M-A" . marginalia-cycle)) + + ;; The :init section is always executed. + :init + + ;; Marginalia must be activated in the :init section of use-package such that + ;; the mode gets enabled right away. Note that this forces loading the + ;; package. + (marginalia-mode)) + +(use-package doom-themes + :ensure t + :config + ;; Global settings (defaults) + (setq doom-themes-enable-bold t ; if nil, bold is universally disabled + doom-themes-enable-italic t) ; if nil, italics is universally disabled + (load-theme 'doom-one t) + + ;; Enable flashing mode-line on errors + (doom-themes-visual-bell-config) + ;; Enable custom neotree theme (nerd-icons must be installed!) + (doom-themes-neotree-config) + ;; or for treemacs users + (setq doom-themes-treemacs-theme "doom-atom") ; use "doom-colors" for less minimal icon theme + (doom-themes-treemacs-config) + ;; Corrects (and improves) org-mode's native fontification. + (doom-themes-org-config)) + +(unless (kylekrein/detect-wsl) + (add-to-list 'default-frame-alist '(alpha-background . 90))) ; For all new frames henceforth + +(use-package which-key + :ensure t + :init + (which-key-mode 1) + :config + (setq which-key-side-window-location 'bottom + which-key-sort-order #'which-key-key-order-alpha + which-key-sort-uppercase-first nil + which-key-add-column-padding 1 + which-key-max-display-columns nil + which-key-min-display-lines 6 + which-key-side-window-slot -10 + which-key-side-window-max-height 0.25 + which-key-idle-delay 0.8 + which-key-max-description-length 25 + which-key-allow-imprecise-window-fit nil + which-key-separator " → " )) + +(when (kylekrein/is-android) + ;;Write all android settings here + (setq touch-screen-keyboard-function t) + (setq touch-screen-display-keyboard t) + + (menu-bar-mode 1) ;; Enable the menu bar + (scroll-bar-mode 1) ;; Enable the scroll bar + (tool-bar-mode 1) ;;Enable the tool bar + (setq use-file-dialog t) ;; file dialog + (setq use-dialog-box t) ;; dialog box + (setq pop-up-windows t) ;; popup windows + (server-start) +) + +(when (kylekrein/detect-wsl) + (setq select-active-regions nil) + (setq select-enable-clipboard 't) + (setq select-enable-primary nil) + (setq interprogram-cut-function #'gui-select-text) +) diff --git a/guix-config/home/emacs/init.el b/guix-config/home/emacs/init.el new file mode 100644 index 0000000..d6623e2 --- /dev/null +++ b/guix-config/home/emacs/init.el @@ -0,0 +1,10 @@ +;;; -*- lexical-binding: t; -*- +(require 'package) +;;https://github.com/wbolster/emacs-direnv/issues/85 +(setenv "PATH" (mapconcat 'identity exec-path ":")) ;;fixes direnv losing nix pkgs +(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) +(package-initialize) +(org-babel-load-file + (expand-file-name + "config.org" + user-emacs-directory)) diff --git a/guix-config/home/services/emacs.scm b/guix-config/home/services/emacs.scm index 6f94094..aff24fe 100644 --- a/guix-config/home/services/emacs.scm +++ b/guix-config/home/services/emacs.scm @@ -31,13 +31,13 @@ (list `(".emacs.d/config.el" ,(mixed-text-file "config.el" ";; Emacs Config from Guix Home\n" - (call-with-input-file (home-emacs-configuration-config-file config) get-string-all))) + "(load-file \"" (home-emacs-configuration-config-file config) "\")\n")) `(".emacs.d/early-config.el" ,(mixed-text-file "early-config.el" ";; Emacs Early Config from Guix Home\n" (string-append "(make-directory \"" package-user-dir "\" t)\n") (string-append "(setq package-user-dir \"" package-user-dir "\")\n") - (home-emacs-configuration-early-config-file config))))) + "(load-file \"" (home-emacs-configuration-early-config-file config) "\")\n")))) (define (home-emacs-profile-service config) (list (home-emacs-configuration-emacs config))) diff --git a/guix-config/home/workstation.scm b/guix-config/home/workstation.scm index 55daa34..2f16108 100644 --- a/guix-config/home/workstation.scm +++ b/guix-config/home/workstation.scm @@ -22,6 +22,7 @@ #:use-module (gnu packages admin) #:use-module (gnu packages fonts) #:use-module (gnu packages games) + #:use-module (gnu packages xdisorg) #:use-module (gnu services) #:use-module (guix gexp) #:use-module (gnu home services shells) @@ -44,8 +45,6 @@ librewolf icecat nheko - supertux - supertuxkart ;birdtray nextcloud-client nautilus @@ -54,6 +53,7 @@ quickshell cava wl-clipboard + cliphist brightnessctl qtmultimedia `(,glib "bin") @@ -83,15 +83,15 @@ (home-dotfiles-configuration (directories '("../../files")))) (service home-secretsd-service-type) - ; (service home-emacs-service-type - ; (home-emacs-configuration - ; (emacs emacs-pgtk) - ; (config-file - ; "../../../.emacs.d/config.el") - ; (early-config-file - ; "../../../.emacs.d/init.el") + (service home-emacs-service-type + (home-emacs-configuration + (emacs emacs-pgtk) + (config-file + (local-file "./emacs/config.el")) + (early-config-file + (local-file "./emacs/init.el")) ; (emacs-packages (list ; emacs-guix)) -;)) +)) ) %base-home-services)))