diff --git a/flake.lock b/flake.lock index 9a8d0c9..dc9409a 100644 --- a/flake.lock +++ b/flake.lock @@ -23,11 +23,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1722519197, - "narHash": "sha256-VEdJmVU2eLFtLqCjTYJd1J7+Go8idAcZoT11IewFiRg=", + "lastModified": 1725407940, + "narHash": "sha256-tiN5Rlg/jiY0tyky+soJZoRzLKbPyIdlQ77xVgREDNM=", "owner": "nixos", "repo": "nixpkgs", - "rev": "05405724efa137a0b899cce5ab4dde463b4fd30b", + "rev": "6f6c45b5134a8ee2e465164811e451dcb5ad86e3", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 507d631..15d8e3c 100644 --- a/flake.nix +++ b/flake.nix @@ -30,11 +30,10 @@ inherit (self) outputs; # Supported systems for your flake packages, shell, etc. systems = [ - "aarch64-linux" - "i686-linux" + # "aarch64-linux" "x86_64-linux" - "aarch64-darwin" - "x86_64-darwin" + # "aarch64-darwin" + # "x86_64-darwin" ]; # This is a function that generates an attribute by calling a function you # pass to it, with each system as an argument @@ -42,7 +41,8 @@ in { # Your custom packages # Accessible through 'nix build', 'nix shell', etc - packages = forAllSystems (system: import ./pkgs nixpkgs.legacyPackages.${system}); + + packages = forAllSystems (system: ((import ./pkgs) {pkgs= nixpkgs.legacyPackages.${system};})); # Formatter for your nix files, available through 'nix fmt' # Other options beside 'alejandra' include 'nixpkgs-fmt' formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.alejandra); diff --git a/home-manager/home.nix b/home-manager/home.nix index 9e9c7f8..ff5c31f 100644 --- a/home-manager/home.nix +++ b/home-manager/home.nix @@ -8,10 +8,9 @@ pkgs, ... }: { - _module.args.azos-utils = import ./utils.nix { lib = lib; }; imports = [ - ./suites + outputs.homeManagerModules ]; nixpkgs = { @@ -27,7 +26,11 @@ }; }; + programs.home-manager.enable = true; + azos.suites.base.enable = true; + # azos.suites.editor.enable = true; + # azos.suites.dev.enable = true; azos.name = "Aner Zakobar"; # TODO: Set your username @@ -44,9 +47,6 @@ graphviz #graphing ]; - programs.home-manager.enable = true; - programs.git.enable = true; - # Nicely reload system units when changing configs systemd.user.startServices = "sd-switch"; diff --git a/home-manager/suites/base/emacs/default.nix b/home-manager/suites/base/emacs/default.nix deleted file mode 100644 index 0ddbb01..0000000 --- a/home-manager/suites/base/emacs/default.nix +++ /dev/null @@ -1,52 +0,0 @@ -{ lib, config, pkgs, azos-utils, ... }: -let - isEnabled = - config.azos.emacs.enable && config.azos.suites.base.enable; - emacspkgs = config.azos.emacs.emacspkg.pkgs; -in -{ - options.azos.emacs.enable = (azos-utils.mkFeatureEnableOption {}); - - options.azos.emacs.emacspkg = lib.mkOption{ - type = lib.types.package; - default = pkgs.emacs; - }; - - options.azos.emacs.pkgs = lib.mkOption{ - default = []; - description = "List of packages for emacs."; - }; - - config = lib.mkIf isEnabled { - azos.emacs.pkgs = [(emacspkgs.trivialBuild (azos-utils.trivialFromOrg { - pname = "azos-emacs-base"; - version = "0.1.6"; - src = ./el/azos-emacs-base.org; - packageRequires = with emacspkgs; [ - evil - evil-collection - magit - vterm - undo-tree - ivy - ivy-hydra - ivy-avy - counsel - counsel-tramp - counsel-projectile - swiper - projectile - ]; - }))]; - - home.packages = with pkgs; - [((emacsPackagesFor config.azos.emacs.emacspkg).emacsWithPackages ( - config.azos.emacs.pkgs - )) ]; - - home.file."/.emacs.el".text = ''(require 'azos-emacs-base)''; - }; - - imports = [ - ]; -} diff --git a/home-manager/suites/base/emacs/el/azos-emacs-base.org b/home-manager/suites/base/emacs/el/azos-emacs-base.org deleted file mode 100644 index fbbd6d1..0000000 --- a/home-manager/suites/base/emacs/el/azos-emacs-base.org +++ /dev/null @@ -1,326 +0,0 @@ -#+title: Aner's Emacs Base Configuration -#+property: header-args :results silent - -* Base setup -** Bootstrapping - -Taken from [[https://stackoverflow.com/questions/151945/how-do-i-control-how-emacs-makes-backup-files][this post on StackOverflow]] - -Backups are moved to a =.cache= directory in order to keep them out of local dirs. - -Follow symlinks - -#+begin_src emacs-lisp -(setq - vc-follow-symlinks t - backup-directory-alist `(("." . "~/.cache/emacs-backups/")) - auto-save-file-name-transforms '((".*" "~/.cache/emacs-backups/" t)) - backup-by-copying t - delete-old-versions t - kept-new-versions 6 - kept-old-versions 2 - version-control t - gc-cons-threshold 100000000 ;Setting garbage collection to 100M. -) - -#+end_src - -Make sure CL is loaded - -CL is a base library that has a bunch of useful stuff, primarily for lists. -We are using the built-in version, no need to pull from anywhere. -This just makes sure the code is loaded early on for later use. - -#+begin_src emacs-lisp -(require 'cl-lib) -#+end_src - -** Keymap setup - -In this section global keybindings are defined using a global minor mode. - -First, utility functions that will be bound are defined. - -The first, =azos/set-window-width= is a helper function that resizes a window. Used because I wanted a function -that resizes a window to 85 cols easily. - -The second, =azos/open-conf-file=, opens the configuration file. - -#+begin_src emacs-lisp -(defun azos/set-window-width (n) - (adjust-window-trailing-edge (selected-window) ( - n (window-width)) t)) - -(defun azos/open-conf-file () - (interactive) - (find-file (concat user-emacs-directory "config.org"))) -#+end_src - -Now let's define keybindings. To start, we'd like =M-o= to be available to us, so let's unbind it. - -#+begin_src emacs-lisp -;Unbind face menu map -(define-key global-map (kbd "M-o") nil) -#+end_src - -This creates an "open keymap", a bunch of keybindings we'll use to open basic applications and files. -This will be mapped to =M-o=, and things will be opened form this sub-menu. -We'll start it with a binding to open the conf file with =M-o o= (MOO!) - -Setting of keybindings based on [[https://stackoverflow.com/questions/49853494/the-best-way-to-set-a-key-to-do-nothing][this]] - -#+begin_src emacs-lisp -;We'll define a basic keymap and already load window-manip funcs -(defvar azos/global-minor-mode/open-keymap - (let ((map (make-sparse-keymap))) - (define-key map (kbd "o") 'azos/open-conf-file) - map) - "global keymap for opening stuff on azos") -#+end_src - -At this stage a minor-mode-map is defined with keybindings, and an accompanying minor-mode is added. - -#+begin_src emacs-lisp -(defvar azos/global-minor-mode/keymap - (let ((map (make-sparse-keymap))) - - ;Window movement and manipulation - (define-key map (kbd "M-h") 'windmove-left) - (define-key map (kbd "M-l") 'windmove-right) - (define-key map (kbd "M-k") 'windmove-up) - (define-key map (kbd "M-j") 'windmove-down) - - (define-key map (kbd "M-") 'windmove-left) - (define-key map (kbd "M-") 'windmove-right) - (define-key map (kbd "M-") 'windmove-up) - (define-key map (kbd "M-") 'windmove-down) - (define-key map (kbd "M-d M-d") 'delete-window) - (define-key map (kbd "M-d D") 'kill-buffer-and-window) - (define-key map (kbd "M-\\") 'split-window-horizontally) - (define-key map (kbd "M-\-") 'split-window-vertically) - (define-key map (kbd "M-d R") (lambda () (interactive) - (set-window-width 85))) - (define-key map (kbd "M-o") azos/global-minor-mode/open-keymap) - map) - "azos/global-minor-mode keymap.") - -(define-minor-mode azos/global-minor-mode - "A minor mode for azos global keymaps." - :init-value t - :lighter "azos" - :keymap azos/global-minor-mode/keymap) - -(azos/global-minor-mode 1) -#+end_src - -This keymap will be referenced many times during this document at relevant points. - -Keymaps are included with relevant sections. - -** EVIL mode - -Using evil mode. - -This section includes unbinding =C-w= (I honestly forget why). - -This section binds keys for changing window size. Done here because can only do after evil loads. - -Unbinding C-w taken from https://stackoverflow.com/questions/24988406/unbinding-evils-c-w-mappings - -#+begin_src emacs-lisp -(setq evil-want-keybinding nil) - -(use-package evil - :init - (setq evil-want-C-i-jump nil) - :config - (require 'evil ) - (evil-mode 1) - - :bind - (:map azos/global-minor-mode/keymap - ("M-w h" . evil-window-decreace-width) - ("M-w l" . evil-window-increase-width) - ("M-w k" . evil-window-decrease-height) - ("M-w j" . evil-window-increase-height)) -) -#+end_src - -Loading evil collection. Functions from this package will be referenced many times later in the configuration. - -#+begin_src emacs-lisp -(use-package evil-collection - :config - (setq evil-collection-setup-minibuffer t) -) -#+end_src - -Setting theme colors - -#+begin_src emacs-lisp -(defvar azos/evil-color-normal "LightGoldenrod1") -(defvar azos/evil-color-emacs "LightBlue1") -(defvar azos/evil-color-insert "PaleGreen1") -(defvar azos/evil-color-replace "LightPink") -(defvar azos/evil-color-motion "LightCyan") -(defvar azos/evil-color-visual "LightGray") -(defvar azos/evil-color-operate "sandy brown") -#+end_src - -** Undo tree - -Loading =undo-tree= for undo/redo functionality with evil. - -Redo taken from https://github.com/syl20bnr/spacemacs/issues/14036 - -#+begin_src emacs-lisp -(use-package undo-tree - :after evil - :config - (evil-set-undo-system 'undo-tree) - (setq undo-tree-history-directory-alist - (list (cons "." (concat user-emacs-directory "undo-tree")))) - (global-undo-tree-mode 1) -) -#+end_src - -** IVY - -Enabling IVY. Taken from [[https://github.com/abo-abo/swiper][their website]]. - -Using ivy, hydra, counsel. - -#+begin_src emacs-lisp -(use-package ivy - :custom - (ivy-use-virtual-buffers t) - (enable-recursive-minibuffers t) - (ivy-count-format "(%d/%d) ") - :config - (ivy-mode 1) -) - -(use-package ivy-hydra - :after ivy) -(use-package ivy-avy - :after ivy) -(use-package counsel - :after ivy - - :bind - (:map azos/global-minor-mode/keymap - ("M-i" . counsel-imenu) - ("M-b" . counsel-switch-buffer) - ("C-x C-f" . counsel-find-file)) - (:map azos/global-minor-mode/open-keymap - ("l" . counsel-linux-app)) -) -#+end_src - -Using swiper. Replacing evil search with swiper search. - -#+begin_src emacs-lisp -(use-package swiper - :after ivy evil - :config - (setq evil-search-module 'swiper-isearch) - - :bind - (:map azos/global-minor-mode/keymap - ("C-s" . swiper-isearch)) -) -#+end_src - -Setting up keymaps - -#+begin_src emacs-lisp -(evil-collection-ivy-setup) -#+end_src - -** Projectile - -Startup up projectile. - -A config line here disables modeline display because I don't want my modeline to be cluttered. - -Mapping modeline commands to =M-p= prefix. Also adding a shortcut to add project. - -#+begin_src emacs-lisp -(use-package projectile - :config - (projectile-mode +1) - (setq projectile-mode-line-function (lambda () "")) - :bind - (:map projectile-command-map - ("a" . projectile-add-known-project) - ) - (:map azos/global-minor-mode/keymap - ("M-p" . projectile-command-map)) -) -#+end_src - -Ivy for projectile: -Parts taken from [[https://emacs.stackexchange.com/questions/40787/display-corresponding-key-binding-of-command-during-m-x-completion][this post]] and [[https://emacs.stackexchange.com/questions/38841/counsel-m-x-always-shows][this post]] from StackOverflow. - -Helps with many functions to use counsel's/ivy's autocomplete with projectile. - -#+begin_src emacs-lisp -(use-package counsel-projectile - :after counsel projectile - :config - (counsel-projectile-mode +1) - (setq projectile-completion-system 'ivy) - ;Making counsel start with empty regex - (when (commandp 'counsel-M-x) - (global-set-key [remap execute-extended-command] 'counsel-M-x)) - (setcdr (assoc 'counsel-M-x ivy-initial-inputs-alist) "") -) -#+end_src - - -** Tramp - -Ensuring tramp is loaded, and loading counsel-tramp for easy tramping. - -#+begin_src emacs-lisp -(use-package tramp - :straight (:type built-in)) - -(use-package counsel-tramp) -#+end_src - -** Assorted utility functions - -Defining a function to copy filename. - -#+begin_src emacs-lisp -(defun azos/copy-file-name () (interactive) - (let ((fpath buffer-file-name)) - (if fpath (kill-new fpath) (message "No current file!")))) -#+end_src - -Need to define this here so that other parts of code have access to it - -#+begin_src emacs-lisp -(defun azos/font-candidate (&rest fonts) - "Return existing font which first match." - (cl-find-if (lambda (f) (find-font (font-spec :name f))) fonts)) -#+end_src - -#+begin_src emacs-lisp -(defun azos/re-seq (regexp string) - "Get a list of all regexp matches in a string" - (save-match-data - (let ((pos 0) - matches) - (while (string-match regexp string pos) - (push (match-string 0 string) matches) - (setq pos (match-end 0))) - matches))) -#+end_src - -** Tie it up - -#+begin_src emacs-lisp -(provide 'azos-emacs-base) -#+end_src - diff --git a/home-manager/suites/default.nix b/home-manager/suites/default.nix deleted file mode 100644 index 186eb78..0000000 --- a/home-manager/suites/default.nix +++ /dev/null @@ -1,16 +0,0 @@ -#https://xeiaso.net/talks/asg-2023-nixos/ example -{ lib, config, pkgs, options, azos-utils, ... }: -{ - # options.azos.suites.base.enable = azos-utils.mkSuiteEnableOption { - # suiteDependents = ["station"]; - # }; - - # options.azos.suites.station.enable = azos-utils.mkSuiteEnableOption { - # suiteDependents = []; - # }; - - imports = [ - ./base - ./station - ]; -} diff --git a/modules/home-manager/default.nix b/modules/home-manager/default.nix index 43e8fb7..de312e7 100644 --- a/modules/home-manager/default.nix +++ b/modules/home-manager/default.nix @@ -1,5 +1,3 @@ -# Add your reusable home-manager modules to this directory, on their own file (https://nixos.wiki/wiki/Module). -# These should be stuff you would like to share with others, not your personal configurations. { - # List your module files here + imports = [ ./suites ]; } diff --git a/home-manager/suites/base/default.nix b/modules/home-manager/suites/base/default.nix similarity index 79% rename from home-manager/suites/base/default.nix rename to modules/home-manager/suites/base/default.nix index 7ee0e06..9757025 100644 --- a/home-manager/suites/base/default.nix +++ b/modules/home-manager/suites/base/default.nix @@ -3,16 +3,11 @@ { options.azos.suites.base.enable = (azos-utils.mkSuiteEnableOption {}); - options.azos.suites.face.enable = lib.mkOption { - type = lib.types.bool; - default = true; - }; - - imports = [ ./emacs ./python ./gpg-agent + ./git ./name.nix ]; @@ -21,4 +16,5 @@ type = lib.types.str; description = "Your full name."; }; + } diff --git a/modules/home-manager/suites/base/emacs/default.nix b/modules/home-manager/suites/base/emacs/default.nix new file mode 100644 index 0000000..beadcc4 --- /dev/null +++ b/modules/home-manager/suites/base/emacs/default.nix @@ -0,0 +1,51 @@ +{ lib, config, pkgs, azos-utils, outputs, ... }: +let + isEnabled = + config.azos.emacs.enable && config.azos.suites.base.enable; + emacspkgs = config.azos.emacs.emacspkg.pkgs; + localPkgName = "azos-emacs-base"; +in +{ + options.azos.emacs.enable = (azos-utils.mkFeatureEnableOption { + description = "Enables EMACS installation.";}); + + options.azos.emacs.emacspkg = lib.mkOption{ + type = lib.types.package; + default = pkgs.emacs; + description = "The base package to use for Emacs."; + }; + + options.azos.emacs.pkgs = lib.mkOption{ + default = []; + description = "List of packages for Emacs."; + }; + + options.azos.emacs.enabledSuites = lib.mkOption{ + default = []; + description = "List of enabled suite names for Emacs. Used to enable the " + + "custom packages in init.el."; + }; + + #Set config + config = lib.mkIf isEnabled { + #Base emacs suite definition + azos.emacs.pkgs = [pkgs.azos.emacs.base]; + + azos.emacs.enabledSuites = [localPkgName]; + + #Global instantiation of Emacs + programs.emacs = { + enable = true; + package = + ((pkgs.emacsPackagesFor config.azos.emacs.emacspkg).emacsWithPackages ( + config.azos.emacs.pkgs + )); + extraConfig = lib.strings.concatStringsSep "\n" + (builtins.map (s : "(require '" + s + ")\n") + config.azos.emacs.enabledSuites); + }; + + }; + + # imports = [./vterm.nix]; +} diff --git a/modules/home-manager/suites/base/emacs/el/azos-emacs-vterm.org b/modules/home-manager/suites/base/emacs/el/azos-emacs-vterm.org new file mode 100644 index 0000000..f66076b --- /dev/null +++ b/modules/home-manager/suites/base/emacs/el/azos-emacs-vterm.org @@ -0,0 +1,20 @@ +#+title: Aner's Emacs Vterm Configuration +#+property: header-args :results silent + +* Vterm + +#+begin_src emacs-lisp +(require 'azos-emacs-base) + +(use-package vterm + :if (member system-type '(gnu gnu/linux)) + :config + (add-hook 'vterm-mode-hook + (lambda () (setq-local global-hl-line-mode nil))) + + (evil-collection-define-key 'normal 'vterm-mode-map + (kbd "p") 'vterm-yank) + (setq vterm-timer-delay 0.01 + vterm-term-environment-variable "xterm-256color")) +#+end_src + diff --git a/modules/home-manager/suites/base/emacs/vterm.nix b/modules/home-manager/suites/base/emacs/vterm.nix new file mode 100644 index 0000000..8b3a72a --- /dev/null +++ b/modules/home-manager/suites/base/emacs/vterm.nix @@ -0,0 +1,29 @@ +{ lib, config, pkgs, azos-utils, ... }: +let + isEnabled = + config.azos.emacs.enable && config.azos.suites.editor.enable && + config.azos.emacs.vterm.enable; + emacspkgs = config.azos.emacs.emacspkg.pkgs; + localPkgName = "azos-emacs-vterm"; +in +{ + options.azos.emacs.vterm.enable = (azos-utils.mkFeatureEnableOption { + description = "Enables Emacs VTERM installation.";}); + + #Set config + config = lib.mkIf isEnabled { + + #Base emacs suite definition + azos.emacs.pkgs = [(emacspkgs.trivialBuild (azos-utils.trivialFromOrg { + pname = localPkgName; + version = "0.1.6"; + src = ./el/azos-emacs-vterm.org; + packageRequires = with emacspkgs; [ + vterm + ]; + }))]; + + azos.emacs.enabledSuites = [localPkgName]; + }; + +} diff --git a/modules/home-manager/suites/base/git/default.nix b/modules/home-manager/suites/base/git/default.nix new file mode 100644 index 0000000..da2b9b6 --- /dev/null +++ b/modules/home-manager/suites/base/git/default.nix @@ -0,0 +1,13 @@ +{ lib, config, pkgs, azos-utils, ... }: +let + isEnabled = + config.azos.git.enable && + config.azos.suites.base.enable; +in +{ + options.azos.git.enable = (azos-utils.mkFeatureEnableOption {}); + + config = lib.mkIf isEnabled { + programs.git.enable = true; + }; +} diff --git a/home-manager/suites/base/gpg-agent/default.nix b/modules/home-manager/suites/base/gpg-agent/default.nix similarity index 100% rename from home-manager/suites/base/gpg-agent/default.nix rename to modules/home-manager/suites/base/gpg-agent/default.nix diff --git a/home-manager/suites/base/gpg-agent/gpg-agent.conf b/modules/home-manager/suites/base/gpg-agent/gpg-agent.conf similarity index 100% rename from home-manager/suites/base/gpg-agent/gpg-agent.conf rename to modules/home-manager/suites/base/gpg-agent/gpg-agent.conf diff --git a/home-manager/suites/base/name.nix b/modules/home-manager/suites/base/name.nix similarity index 100% rename from home-manager/suites/base/name.nix rename to modules/home-manager/suites/base/name.nix diff --git a/home-manager/suites/base/python/default.nix b/modules/home-manager/suites/base/python/default.nix similarity index 89% rename from home-manager/suites/base/python/default.nix rename to modules/home-manager/suites/base/python/default.nix index c47c908..b890f86 100644 --- a/home-manager/suites/base/python/default.nix +++ b/modules/home-manager/suites/base/python/default.nix @@ -18,10 +18,6 @@ in }; config = lib.mkIf isEnabled { - azos.python.pkgs = with pythonpkgs; [ - graphviz - pygments - ]; home.packages = with pkgs; [(config.azos.python.pythonpkg.withPackages (python-pkgs: config.azos.python.pkgs)) diff --git a/modules/home-manager/suites/default.nix b/modules/home-manager/suites/default.nix new file mode 100644 index 0000000..f20f3f3 --- /dev/null +++ b/modules/home-manager/suites/default.nix @@ -0,0 +1,12 @@ +#https://xeiaso.net/talks/asg-2023-nixos/ example +{ lib, config, pkgs, options, azos-utils, ... }: +{ + _module.args.azos-utils = import ./utils.nix { lib = lib; }; + + imports = [ + ./base + ./station + ./dev + ./editor + ]; +} diff --git a/modules/home-manager/suites/dev/default.nix b/modules/home-manager/suites/dev/default.nix new file mode 100644 index 0000000..b7ae4ce --- /dev/null +++ b/modules/home-manager/suites/dev/default.nix @@ -0,0 +1,9 @@ +#https://xeiaso.net/talks/asg-2023-nixos/ example +{ lib, config, pkgs, options, azos-utils, ... }: +{ + options.azos.suites.dev.enable = (azos-utils.mkSuiteEnableOption {}); + + imports = [ + ./emacs + ]; +} diff --git a/modules/home-manager/suites/dev/emacs/default.nix b/modules/home-manager/suites/dev/emacs/default.nix new file mode 100644 index 0000000..659e871 --- /dev/null +++ b/modules/home-manager/suites/dev/emacs/default.nix @@ -0,0 +1,31 @@ +{ lib, config, pkgs, azos-utils, ... }: +let + isEnabled = + config.azos.emacs.enable && config.azos.suites.dev.enable; + emacspkgs = config.azos.emacs.emacspkg.pkgs; + localPkgName = "azos-emacs-dev"; +in +{ + #Set config + config = lib.mkIf isEnabled { + + #Base emacs suite definition + azos.emacs.pkgs = [(emacspkgs.trivialBuild (azos-utils.trivialFromOrg { + pname = localPkgName; + version = "0.1.6"; + src = ./el/azos-emacs-dev.org; + packageRequires = with emacspkgs; [ + flycheck + cmake-mode + yaml + nix-mode + python + rust-mode + ein + ]; + }))]; + + azos.emacs.enabledSuites = [localPkgName]; + }; + +} diff --git a/modules/home-manager/suites/dev/emacs/el/azos-emacs-dev.org b/modules/home-manager/suites/dev/emacs/el/azos-emacs-dev.org new file mode 100644 index 0000000..046ce1f --- /dev/null +++ b/modules/home-manager/suites/dev/emacs/el/azos-emacs-dev.org @@ -0,0 +1,128 @@ +#+title: Aner's Emacs Development Configuration +#+property: header-args :results silent + +* Base dev + +** Require + +#+begin_src emacs-lisp +(require 'azos-emacs-base) +#+end_src + +** Flycheck + +Flycheck is for syntax checking. Mode-specific configs in their relevant sections. + +#+begin_src emacs-lisp +(use-package flycheck + :config + (global-flycheck-mode 1) +) +#+end_src + +* Dev modes +** Irony-mode + +Must work on this. While it does work, can get slow and for weird projects can +show errors. + +Namespace indent disabling based on: +https://stackoverflow.com/questions/13825188/suppress-c-namespace-indentation-in-emacs + +#+begin_src emacs-lisp +;; == irony-mode == +(use-package irony + :ensure t + :defer t + :init + (add-hook 'c++-mode-hook 'irony-mode) + (add-hook 'c-mode-hook 'irony-mode) + (add-hook 'objc-mode-hook 'irony-mode) + :config + ;; replace the `completion-at-point' and `complete-symbol' bindings in + ;; irony-mode's buffers by irony-mode's function + (defun azos/irony-mode-hook () + (define-key irony-mode-map [remap completion-at-point] + 'irony-completion-at-point-async) + (define-key irony-mode-map [remap complete-symbol] + 'irony-completion-at-point-async)) + (add-hook 'irony-mode-hook 'azos/irony-mode-hook) + (add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options) + + (defconst azos/cc-style + '("gnu" + (c-offsets-alist . ((innamespace . [0]))) + (c-basic-offset . 4))) + + (c-add-style "azos/cc-style" azos/cc-style) + (add-hook 'irony-mode-hook (lambda () (c-set-style "azos/cc-style"))) + ) +#+end_src + +Integration with flycheck + +#+begin_src emacs-lisp +(use-package flycheck-irony + :after flycheck irony + :config + (add-hook 'flycheck-mode-hook #'flycheck-irony-setup) + (add-hook 'c++-mode-hook (lambda () (setq flycheck-checker 'irony))) +) +#+end_src + +** CMake + +#+begin_src emacs-lisp +(use-package cmake-mode) +#+end_src + +** YAML + +#+begin_src emacs-lisp +(use-package yaml-mode) +#+end_src + +** Nix + +#+begin_src emacs-lisp +(use-package nix-mode) +#+end_src + +** Python + +#+begin_src emacs-lisp +(setq + ;; python-shell-interpreter "python3" + python-shell-completion-native-enable nil) + +(defun anerenv/python/set-fringes () "Sets fringes for python" + (setq left-fringe-width 10 right-fringe-width 0)) + +(add-hook 'python-mode-hook 'anerenv/python/set-fringes) + +(use-package elpy + :ensure t + :defer t) + ;; :init + ;; (elpy-enable)) + +(define-key anerenv/global-minor-mode/open-keymap + (kbd "r p") 'run-python) +#+end_src + +** Rust + +#+begin_src emacs-lisp +(use-package rust-mode) +#+end_src + +** Jupyter (ein) + +#+begin_src emacs-lisp +(use-package ein + :config + (setq ein:output-area-inlined-images t) + (add-hook 'ein:notebook-mode-hook (lambda () (progn + ;; (elpy-mode -1) + (define-key ein:notebook-mode-map (kbd "C-c C-k") nil))))) +#+end_src diff --git a/modules/home-manager/suites/editor/default.nix b/modules/home-manager/suites/editor/default.nix new file mode 100644 index 0000000..110ee5a --- /dev/null +++ b/modules/home-manager/suites/editor/default.nix @@ -0,0 +1,9 @@ +#https://xeiaso.net/talks/asg-2023-nixos/ example +{ lib, config, pkgs, options, azos-utils, ... }: +{ + options.azos.suites.editor.enable = (azos-utils.mkSuiteEnableOption {}); + + imports = [ + ./emacs + ]; +} diff --git a/modules/home-manager/suites/editor/emacs/default.nix b/modules/home-manager/suites/editor/emacs/default.nix new file mode 100644 index 0000000..f91fa6b --- /dev/null +++ b/modules/home-manager/suites/editor/emacs/default.nix @@ -0,0 +1,29 @@ +{ lib, config, pkgs, azos-utils, ... }: +let + isEnabled = + config.azos.emacs.enable && config.azos.suites.dev.enable; + emacspkgs = config.azos.emacs.emacspkg.pkgs; + pythonpkgs = config.azos.python.pythonpkg.pkgs; + localPkgName = "azos-emacs-editor"; +in +{ + #Set config + config = lib.mkIf isEnabled { + + #Base emacs suite definition + azos.emacs.pkgs = [(emacspkgs.trivialBuild (azos-utils.trivialFromOrg { + pname = localPkgName; + version = "0.1.6"; + src = ./el/azos-emacs-editor.org; + packageRequires = with emacspkgs; [ + graphviz-dot-mode + markdown-mode + ]; + }))]; + + azos.emacs.enabledSuites = [localPkgName]; + + azos.python.pkgs = with pythonpkgs; [ graphviz pygments ]; + }; + +} diff --git a/modules/home-manager/suites/editor/emacs/el/azos-emacs-editor.org b/modules/home-manager/suites/editor/emacs/el/azos-emacs-editor.org new file mode 100644 index 0000000..f87a126 --- /dev/null +++ b/modules/home-manager/suites/editor/emacs/el/azos-emacs-editor.org @@ -0,0 +1,176 @@ +#+title: Aner's Emacs Editor Configuration +#+property: header-args :results silent + +* Base dev + +** Require + +#+begin_src emacs-lisp +(require 'azos-emacs-base) +#+end_src + +* Editor modes + +** Pandoc + +Pandoc mode lets us export different formats to PDF. + +Added for use with markdown. + +Binding to startup is 'C-c /' + +#+begin_src emacs-lisp +(use-package pandoc-mode + :hook + (markdown-mode . pandoc-mode)) +#+end_src + +** Graphviz + +#+begin_src emacs-lisp +(use-package graphviz-dot) +#+end_src + +** Markdown + +Based on [[https://www.reddit.com/r/emacs/comments/u5owr4/how_to_enable_variablepitchmode_for_markdownmode/][this]] post +detailing variable pitch. + +We default to github-flavored markdown and show it as variable pitch. + +#+begin_src emacs-lisp +(use-package markdown-mode + :mode (("\\.md$" . gfm-mode) + ("\\.mkd$" . gfm-mode)) + :hook (gfm-mode . variable-pitch-mode) + :diminish markdown-live-preview-mode + :config + (when (bound-and-true-p lsp-mode) + (variable-pitch-mode -1)) + (set-face-attribute 'markdown-pre-face nil + :background "LemonChiffon1" :extend t) + ) +#+end_src + +Let's add a TOC + +#+begin_src emacs-lisp +(use-package markdown-toc) +#+end_src + + +* ORG + +** PDF exporting + +#+begin_src emacs-lisp +(setq org-latex-listings 'minted + org-export-babel-evaluate nil + org-latex-pdf-process + (list (concat "latexmk -xelatex -shell-escape -interaction=nonstopmode " + "-output-directory=%o %f ; latexmk -c %f"))) + +(require 'ox-latex) +(unless (boundp 'org-latex-classes) + (setq org-latex-classes nil)) +#+end_src + +This code removes unecessary files after each export + +#+begin_src emacs-lisp +(add-to-list 'org-latex-logfiles-extensions "tex") +#+end_src + +Creating classes + +#+begin_src emacs-lisp +(defvar anerenv/latex-class-common-header + "[DEFAULT-PACKAGES] +\\usepackage{polyglossia} +\\usepackage{tabularx} +\\usepackage[cache=false]{minted} +\\usepackage{xcolor} +\\usepackage{indentfirst} +\\usepackage{amsfonts} +\\usepackage{transparent} +\\usepackage{amsmath} +\\usepackage{braket} +\\usepackage{dsfont} +\\definecolor{codebg}{rgb}{0.95,0.95,0.95} +\\setdefaultlanguage{english} +\\setlength{\\parindent}{0in} + + +\\DeclareMathOperator*{\\argmax}{arg\\,max} +\\DeclareMathOperator*{\\argmin}{arg\\,min} +\\newfontfamily\\hebrewfont{LiberationSans}[Script=Hebrew] +\\newfontfamily\\hebrewfonttt{LiberationSans}[Script=Hebrew] +\\newfontfamily\\hebrewfontsf{LiberationSans}[Script=Hebrew] +\\setotherlanguage{hebrew} +" "Default common class header") + +(setq org-latex-classes + (list (list "article" +(concat "\\documentclass{article} +" anerenv/latex-class-common-header +"\\setminted{ + bgcolor=codebg, + breaklines=true, + mathescape, + fontsize=\\scriptsize, + linenos=false, +} +") + '("\\section{%s}" . "\\section*{%s}") + '("\\subsection{%s}" . "\\subsection*{%s}") + '("\\subsubsection{%s}" . "\\subsubsection*{%s}") + '("\\paragraph{%s}" . "\\paragraph*{%s}") + '("\\subparagraph{%s}" . "\\subparagraph*{%s}")) + (list "beamer" +(concat "\\documentclass{beamer} +" anerenv/latex-class-common-header +"\\setminted{ + bgcolor={}, + breaklines=true, + mathescape, + fontsize=\\scriptsize, + linenos=false, +} +") + '("\\section{%s}" . "\\section*{%s}") + '("\\subsection{%s}" . "\\subsection*{%s}") + '("\\subsubsection{%s}" . "\\subsubsection*{%s}") + '("\\paragraph{%s}" . "\\paragraph*{%s}") + '("\\subparagraph{%s}" . "\\subparagraph*{%s}"))) + ) +#+end_src + +This should render Hebrew text. + +#+begin_export latex +\begin{hebrew} +#+end_export +זה אמור לעבוד +#+begin_export latex +\end{hebrew} +#+end_export + +** DOCX exporting + +Taken from https://www.reddit.com/r/emacs/comments/zjv1gj/org_files_to_docx/ + +#+begin_src emacs-lisp +(defun anerenv/org/export-docx-with-pandoc () + "Use Pandoc to convert .org to .docx. +Comments: +- The `-N' flag numbers the headers lines. +- Use the `--from org' flag to have this function work on files + that are in Org syntax but do not have a .org extension" + (interactive) + (message "exporting .org to .docx") + (shell-command + (concat "pandoc -N --from org " (buffer-file-name) + " -o " + (file-name-sans-extension (buffer-file-name)) + (format-time-string "-%Y-%m-%d-%H%M%S") ".docx"))) +#+end_src diff --git a/modules/home-manager/suites/editor/tex.nix b/modules/home-manager/suites/editor/tex.nix new file mode 100644 index 0000000..2b74141 --- /dev/null +++ b/modules/home-manager/suites/editor/tex.nix @@ -0,0 +1,40 @@ +{ lib, config, pkgs, azos-utils, ... }: +let + isEnabled = + config.azos.tex.enable && config.azos.suites.editor.enable; +in +{ + options.azos.tex.enable = (azos-utils.mkFeatureEnableOption {}); + + options.azos.tex.pkgs = lib.mkOption{ + default = []; + description = "List of packages for tex."; + }; + + config = lib.mkIf isEnabled { + azos.tex.pkgs = with pkgs.texlive; [ + combined.scheme-basic + dvisvgm + dvipng + wrapfig + amsmath + ulem + hyperref + capt-of + + polyglossia + xcolor + amsmath + amsfonts + braket + hebrew-fonts + ]; + + home.packages = with pkgs; [(texlive.combine azos.tex.pkgs)]; + }; + + imports = [ + ]; + + +} diff --git a/home-manager/suites/station/default.nix b/modules/home-manager/suites/station/default.nix similarity index 100% rename from home-manager/suites/station/default.nix rename to modules/home-manager/suites/station/default.nix diff --git a/home-manager/utils.nix b/modules/home-manager/suites/utils.nix similarity index 59% rename from home-manager/utils.nix rename to modules/home-manager/suites/utils.nix index 6817232..7734786 100644 --- a/home-manager/utils.nix +++ b/modules/home-manager/suites/utils.nix @@ -1,29 +1,5 @@ { lib, ... }: { - # mkFeatureEnableOption = { suiteEnable, ...} @ attrs : - # lib.mkOption (builtins.removeAttrs (lib.mergeAttrs attrs { - # default = true; - # example = true; - # type = lib.types.bool; - # apply = old: suiteEnable && old; - # }) ["suiteEnable"]); - - # mkDependentFeatureEnableOption = { suiteEnable, otherOption, ...} @ attrs : - # lib.mkOption (builtins.removeAttrs (lib.mergeAttrs attrs { - # default = true; - # example = true; - # type = lib.types.bool; - # apply = old: suiteEnable && otherOption && old; - # }) ["suiteEnable" "otherOption"]); - - # mkSuiteEnableOption = { suiteDependents, ... } @ attrs : - # lib.mkOption lib.mergeAttrs attrs { - # default = []; - # example = []; - # type = lib.types.list; - # apply = old: old || lib.lists.any suiteEnabledPred suiteDependents; - # }; - mkFeatureEnableOption = { ... } @ attrs : lib.mkOption (lib.mergeAttrs attrs { default = true; diff --git a/pkgs/azos-emacs-base.nix b/pkgs/azos-emacs-base.nix new file mode 100644 index 0000000..d6cccff --- /dev/null +++ b/pkgs/azos-emacs-base.nix @@ -0,0 +1,29 @@ +{ + orgTrivialBuild, + epkgs +}: +orgTrivialBuild { + pname = "azos-emacs-base"; + version = "0.1.6"; + src = ./elisp/azos-emacs-base.org; + packageRequires = with epkgs; [ + evil + evil-collection + magit + undo-tree + ivy + ivy-hydra + ivy-avy + counsel + counsel-tramp + counsel-projectile + swiper + projectile + which-key + yasnippet + evil-nerd-commenter + company + olivetti #FLYCHECK PANDOC + dired-subtree + ]; +} diff --git a/pkgs/azos-trivial-org.nix b/pkgs/azos-trivial-org.nix new file mode 100644 index 0000000..ab39e07 --- /dev/null +++ b/pkgs/azos-trivial-org.nix @@ -0,0 +1,45 @@ +# trivial builder for Emacs packages + +{ callPackage, lib, epkgs, ... }@envargs: + +let + libBuildHelper = epkgs.lib-build-helper; +in + +libBuildHelper.extendMkDerivation' epkgs.trivialBuild (finalAttrs: + +args: + +{ + preBuild = args.preBuild or '' + for file in ./*.org + do + emacs --batch --eval "(require 'org)" --eval "(org-babel-tangle-file \"$file\" (concat (file-name-sans-extension \"$file\") \".el\") \"emacs-lisp\")" + done + ''; + unpackCmd = args.unpackCmd or '' + case "$curSrc" in + *.el) + # keep original source filename without the hash + local filename=$(basename "$curSrc") + filename="''${filename:33}" + cp $curSrc $filename + chmod +w $filename + sourceRoot="." + ;; + *.org) + # keep original source filename without the hash + local filename=$(basename "$curSrc") + filename="''${filename:33}" + cp $curSrc $filename + chmod +w $filename + sourceRoot="." + ;; + *) + _defaultUnpack "$curSrc" + ;; + esac + ''; +} + +) diff --git a/pkgs/default.nix b/pkgs/default.nix index ff4e7fb..31e1a43 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -1,3 +1,42 @@ -pkgs: { - # example = pkgs.callPackage ./example { }; +{ pkgs } @ args: +let + inherit args; + emacs-pkg = pkgs.emacs; + epkgs = emacs-pkg.pkgs; + trivialBuild = epkgs.trivialBuild; + orgTrivialBuild = attrs : (trivialBuild (pkgs.lib.mergeAttrs attrs { + preBuild = '' + for file in ./*.org + do + emacs --batch --eval "(require 'org)" --eval "(org-babel-tangle-file \"$file\" (concat (file-name-sans-extension \"$file\") \".el\") \"emacs-lisp\")" + done + ''; + unpackCmd = '' + case "$curSrc" in + *.el) + # keep original source filename without the hash + local filename=$(basename "$curSrc") + filename="''${filename:33}" + cp $curSrc $filename + chmod +w $filename + sourceRoot="." + ;; + *.org) + # keep original source filename without the hash + local filename=$(basename "$curSrc") + filename="''${filename:33}" + cp $curSrc $filename + chmod +w $filename + sourceRoot="." + ;; + *) + _defaultUnpack "$curSrc" + ;; + esac + ''; + })); +in +{ + azos.emacs.base = (pkgs.callPackage ./azos-emacs-base.nix + { orgTrivialBuild = orgTrivialBuild; epkgs = epkgs; }); } diff --git a/pkgs/elisp/azos-emacs-base.org b/pkgs/elisp/azos-emacs-base.org new file mode 100644 index 0000000..99c81cd --- /dev/null +++ b/pkgs/elisp/azos-emacs-base.org @@ -0,0 +1,906 @@ +#+title: Aner's Emacs Base Configuration +#+property: header-args :results silent + +* Base setup +** Bootstrapping + +Partially based on [[https://stackoverflow.com/questions/151945/how-do-i-control-how-emacs-makes-backup-files][this post on StackOverflow]]. Setting backups, external custom file. + +#+begin_src emacs-lisp +(setq + vc-follow-symlinks t ;Follow symlinks + ;Backup location TODO FIND IF RELEVANT FOR NIX + backup-directory-alist `(("." . "~/.cache/emacs-backups/")) + auto-save-file-name-transforms '((".*" "~/.cache/emacs-backups/" t)) + backup-by-copying t ;Always copy never link + delete-old-versions t ;Auto delete old backups + kept-new-versions 6 ;Number of versions to keep + kept-old-versions 2 + version-control t ;Backups for files + gc-cons-threshold 100000000 ;Setting garbage collection to 100M. + ;Set external cusotm file + custom-file (expand-file-name "custom.el" user-emacs-directory) +) + +#+end_src + +Load custom file + +#+begin_src emacs-lisp +(if (file-exists-p custom-file) (load custom-file)) +#+end_src + +** Utility functions + +*** CL + +CL is a base library that has a bunch of useful stuff, primarily for lists. +We are using the built-in version, no need to pull from anywhere. +This just makes sure the code is loaded early on for later use. + +#+begin_src emacs-lisp +(require 'cl-lib) +#+end_src + +*** Copy file name + +Defining a function to copy filename. + +#+begin_src emacs-lisp +(defun azos/copy-file-name () (interactive) + (let ((fpath buffer-file-name)) + (if fpath (kill-new fpath) (message "No current file!")))) +#+end_src + +*** Font candidate + +#+begin_src emacs-lisp +(defun azos/font-candidate (&rest fonts) + "Return existing font which first match." + (cl-find-if (lambda (f) (find-font (font-spec :name f))) fonts)) +#+end_src + +*** Regex match function + +#+begin_src emacs-lisp +(defun azos/re-seq (regexp string) + "Get a list of all regexp matches in a string" + (save-match-data + (let ((pos 0) + matches) + (while (string-match regexp string pos) + (push (match-string 0 string) matches) + (setq pos (match-end 0))) + matches))) +#+end_src + +** Keymap setup + +In this section global keybindings are defined using a global minor mode. + +First, utility functions that will be bound are defined. + +The first, =azos/set-window-width= is a helper function that resizes a window. Used because I wanted a function +that resizes a window to 85 cols easily. + +The second, =azos/open-conf-file=, opens the configuration file. + +#+begin_src emacs-lisp +(defun azos/set-window-width (n) + (adjust-window-trailing-edge (selected-window) ( - n (window-width)) t)) + +(defun azos/open-conf-file () + (interactive) + (find-file (concat user-emacs-directory "config.org"))) +#+end_src + +Now let's define keybindings. To start, we'd like =M-o= to be available to us, so let's unbind it. + +#+begin_src emacs-lisp +;Unbind face menu map +(define-key global-map (kbd "M-o") nil) +#+end_src + +This creates an "open keymap", a bunch of keybindings we'll use to open basic applications and files. +This will be mapped to =M-o=, and things will be opened form this sub-menu. +We'll start it with a binding to open the conf file with =M-o o= (MOO!) + +Setting of keybindings based on [[https://stackoverflow.com/questions/49853494/the-best-way-to-set-a-key-to-do-nothing][this]] + +#+begin_src emacs-lisp +;We'll define a basic keymap and already load window-manip funcs +(defvar azos/global-minor-mode/open-keymap + (let ((map (make-sparse-keymap))) + (define-key map (kbd "o") 'azos/open-conf-file) + map) + "global keymap for opening stuff on azos") +#+end_src + +At this stage a minor-mode-map is defined with keybindings, and an accompanying minor-mode is added. + +#+begin_src emacs-lisp +(defvar azos/global-minor-mode/keymap + (let ((map (make-sparse-keymap))) + + ;Window movement and manipulation + (define-key map (kbd "M-h") 'windmove-left) + (define-key map (kbd "M-l") 'windmove-right) + (define-key map (kbd "M-k") 'windmove-up) + (define-key map (kbd "M-j") 'windmove-down) + + (define-key map (kbd "M-") 'windmove-left) + (define-key map (kbd "M-") 'windmove-right) + (define-key map (kbd "M-") 'windmove-up) + (define-key map (kbd "M-") 'windmove-down) + (define-key map (kbd "M-d M-d") 'delete-window) + (define-key map (kbd "M-d D") 'kill-buffer-and-window) + (define-key map (kbd "M-\\") 'split-window-horizontally) + (define-key map (kbd "M-\-") 'split-window-vertically) + (define-key map (kbd "M-d R") (lambda () (interactive) + (set-window-width 85))) + (define-key map (kbd "M-o") azos/global-minor-mode/open-keymap) + map) + "azos/global-minor-mode keymap.") + +(define-minor-mode azos/global-minor-mode + "A minor mode for azos global keymaps." + :init-value t + :lighter "azos" + :keymap azos/global-minor-mode/keymap) + +(azos/global-minor-mode 1) +#+end_src + +This keymap will be referenced many times during this document at relevant points. + +Keymaps are included with relevant sections. + +** EVIL mode + +This section binds keys for changing window size. Done here because can only do after evil loads. + +#+begin_src emacs-lisp +(setq evil-want-keybinding nil) + +(use-package evil + :init + (setq evil-want-C-i-jump nil) + :config + (require 'evil ) + (evil-mode 1) + + :bind + (:map azos/global-minor-mode/keymap + ("M-w h" . evil-window-decreace-width) + ("M-w l" . evil-window-increase-width) + ("M-w k" . evil-window-decrease-height) + ("M-w j" . evil-window-increase-height)) +) +#+end_src + +Loading evil collection. Functions from this package will be referenced many times later in the configuration. + +#+begin_src emacs-lisp +(use-package evil-collection + :config + (setq evil-collection-setup-minibuffer t) +) +#+end_src + +#+begin_src emacs-lisp +(defvar azos/evil-color-normal "LightGoldenrod1") +(defvar azos/evil-color-emacs "LightBlue1") +(defvar azos/evil-color-insert "PaleGreen1") +(defvar azos/evil-color-replace "LightPink") +(defvar azos/evil-color-motion "LightCyan") +(defvar azos/evil-color-visual "LightGray") +(defvar azos/evil-color-operate "sandy brown") +#+end_src + +** IVY + +Enabling IVY. Taken from [[https://github.com/abo-abo/swiper][their website]]. + +Using ivy, hydra, counsel. + +#+begin_src emacs-lisp +(use-package ivy + :custom + (ivy-use-virtual-buffers t) + (enable-recursive-minibuffers t) + (ivy-count-format "(%d/%d) ") + :config + (ivy-mode 1) +) + +(use-package ivy-hydra + :after ivy) +(use-package ivy-avy + :after ivy) +(use-package counsel + :after ivy + + :bind + (:map azos/global-minor-mode/keymap + ("M-i" . counsel-imenu) + ("M-b" . counsel-switch-buffer) + ("C-x C-f" . counsel-find-file)) + (:map azos/global-minor-mode/open-keymap + ("l" . counsel-linux-app)) +) +#+end_src + +Using swiper. Replacing evil search with swiper search. + +#+begin_src emacs-lisp +(use-package swiper + :after ivy evil + :config + (setq evil-search-module 'swiper-isearch) + + :bind + (:map azos/global-minor-mode/keymap + ("C-s" . swiper-isearch)) +) +#+end_src + +Setting up keymaps + +#+begin_src emacs-lisp +(evil-collection-ivy-setup) +#+end_src + +** Assorted utility functions +* UI +** General +*** Clean UI + +Disabling the toolbar, the splash-screen, the menu-bar and the scroll-bar + +#+begin_src emacs-lisp +(menu-bar-mode -1) ; no menu bar +(when (display-graphic-p) + (tool-bar-mode -1) ; no tool bar with icons + (scroll-bar-mode -1) ; no scroll bars + (set-fringe-mode 0)) +#+end_src + +*** Background color + +#+begin_src emacs-lisp +(add-to-list 'default-frame-alist '(background-color . "LightYellow")) +#+end_src + +*** Fringe color + +While we don't actually want fringes (almost at all), some frames use them. + +#+begin_src emacs-lisp +(set-face-attribute 'fringe nil :background "LemonChiffon1") +#+end_src + +*** Window dividers + +#+begin_src emacs-lisp +(setq window-divider-default-bottom-width 1 + window-divider-default-places 'bottom-only) + +(window-divider-mode 1) +#+end_src + +*** Easy Prompt + +#+begin_src emacs-lisp +(defalias 'yes-or-no-p 'y-or-n-p) +#+end_src + +*** Minibuff + +#+begin_src emacs-lisp +(add-hook 'minibuffer-setup-hook + (lambda () + (make-local-variable 'face-remapping-alist) + (add-to-list 'face-remapping-alist + '(default (:background "WhiteSmoke"))))) +#+end_src + +*** Bell + +Disable bell, who needs the bell? + +#+begin_src emacs-lisp +(setq ring-bell-function (lambda () ())) +#+end_src + +*** Olivetti + +Useful to have even if I rarely use it. + +#+begin_src emacs-lisp +(use-package olivetti + :init + (setq olivetti-body-width 96)) +#+end_src + +*** Modeline + +Setting colors + +#+begin_src emacs-lisp +(set-face-attribute 'mode-line nil :box nil :background "AliceBlue") +(set-face-attribute 'mode-line-inactive nil :box nil :background "LightYellow3") +#+end_src + +We use [[https://emacs.stackexchange.com/questions/5529/how-to-right-align-some-items-in-the-modeline][this stackoverflow page]] to make left\right aligned stuff. + +We use [[https://www.reddit.com/r/emacs/comments/4mhphb/spacemacs_how_to_limit_the_length_of_displayed/][this article]] to try and limit the mode name length. + +#+begin_src emacs-lisp +(setq evil-normal-state-tag + (propertize " NORMAL " 'face + (list :background azos/evil-color-normal)) + evil-emacs-state-tag + (propertize " EMACS " 'face + (list :background azos/evil-color-emacs)) + evil-insert-state-tag + (propertize " INSERT " 'face + (list :background azos/evil-color-insert)) + evil-replace-state-tag + (propertize " REPLACE " 'face + (list :background azos/evil-color-replace)) + evil-motion-state-tag + (propertize " MOTION " 'face + (list :background azos/evil-color-motion)) + evil-visual-state-tag + (propertize " VISUAL " 'face + (list :background azos/evil-color-visual)) + evil-operator-state-tag + (propertize " OPERATE " 'face + (list :background azos/evil-color-operate))) + +(defun azos/modeline/modeline-render (left right) + "Return a string of `window-width' length containing LEFT, and RIGHT + aligned respectively." + (let* ((available-width (- (window-width) (length left) 2))) + (format (format " %%s %%%ds " available-width) left right))) + +(setq-default mode-line-buffer-identification + (list -80 (propertized-buffer-identification "%12b"))) + +(setq-default mode-line-format + '((:eval (azos/modeline/modeline-render + ;;Left + (concat + (propertize (format-mode-line "%b") 'face '((:foreground "maroon"))) + (format-mode-line " (%m) ")) + ;;Right + (concat + (format-mode-line "%5lL%4cC ") + evil-mode-line-tag))))) +#+end_src + +*** Notifications + +#+begin_src emacs-lisp +(require 'notifications) +#+end_src + +*** Which-Key + +#+begin_src emacs-lisp +(use-package which-key + :config + (which-key-mode)) +#+end_src + +** Text +*** YASnippet + +Loading yasnippet. Useful for snippeting. Mode-specific snippets defined in relevant sections. + +#+begin_src emacs-lisp +(use-package yasnippet + :config + (yas-global-mode 1) +) +#+end_src + +*** Text font + +This section configures the base fonts. We select fonts if available (have configurations for good defaults in +Linux and Windows). + +Also setting default fixed-pitch and variable-pitch fonts. + +Setting font size to 10. The value to place is font-size * 10 + +Font size 12 for variable pitch. + +The function =font-candidate= is from https://www.gnu.org/software/emacs/manual/html_mono/cl.html. + +#+begin_src emacs-lisp +(let ((variable-font (azos/font-candidate + "Liberation Serif" "Microsoft Sans Serif"))) + (if variable-font + (set-face-attribute 'variable-pitch nil :font variable-font))) + +(let ((fixed-font (azos/font-candidate + "Source Code Pro" "LiberationMono" "Consolas"))) + (if fixed-font (progn + (set-face-attribute 'default nil :font fixed-font) + (set-face-attribute 'fixed-pitch nil :font fixed-font)))) + +(set-face-attribute 'default nil :height 100) +(set-face-attribute 'variable-pitch nil + :height 130 + :weight 'normal + :width 'normal) + +(set-face-attribute 'fixed-pitch nil + :height 100 + :weight 'normal + :width 'normal) + +(defun azos/default-variable-pitch () + (face-remap-add-relative 'default '(:inherit 'variable-pitch))) +#+end_src + +*** Line numbering + +We want line numbering, but only in modes where it makes sense. + +To do this, a custom minor-mode, =azos/global-linum-mode=, is created. +This mode selectively activates linum-mode if the mode is not one of a selected exempt modes. +These exempt modes are defined in =display-line-numbers-exempt-modes=. + +Taken from [[https://www.emacswiki.org/emacs/LineNumbers][this wiki entry]]. + +#+begin_src emacs-lisp +(use-package display-line-numbers + :init + (defcustom azos/display-line-numbers-exempt-modes + '(vterm-mode + eshell-mode + shell-mode + term-mode + ansi-term-mode + magit-mode + magit-diff-mode + notmuch-hello + pdf-view-mode) + "Major modes on which to disable the linum mode, exempts them." + :group 'display-line-numbers + :type 'list + :version "green") + + (define-global-minor-mode azos/global-linum-mode + display-line-numbers-mode + (lambda () (if (and + (not (apply 'derived-mode-p + azos/display-line-numbers-exempt-modes)) + (not (minibufferp))) + (display-line-numbers-mode)))) + + (setq display-line-numbers-type 'visual + display-line-numbers-grow-only 1 + display-line-numbers-width-start 1) + + :config + (azos/global-linum-mode 1) + (set-face-attribute 'line-number nil + :family (face-attribute 'fixed-pitch :family)) +) +#+end_src + +*** Line highlight + +Highlighting line with cursor. + +Modification done to use EVIL colors on highlighted line. + +#+begin_src emacs-lisp +(global-hl-line-mode) +(set-face-attribute 'hl-line nil :background azos/evil-color-emacs) + +(defface hl-line-normal + (list (list t (list :inherit 'hl-line :background azos/evil-color-normal + :extend t))) + "Highlight face for evil normal mode." + :group 'hl-line) + +(defface hl-line-insert + (list (list t (list :inherit 'hl-line :background azos/evil-color-insert + :extend t))) + "Highlight face for evil insert mode." + :group 'hl-line) + +(defface hl-line-emacs + (list (list t (list :inherit 'hl-line :background azos/evil-color-emacs + :extend t))) + "Highlight face for evil insert mode." + :group 'hl-line) + +(defface hl-line-replace + (list (list t (list :inherit 'hl-line :background azos/evil-color-replace + :extend t))) + "Highlight face for evil insert mode." + :group 'hl-line) + +(defface hl-line-motion + (list (list t (list :inherit 'hl-line :background azos/evil-color-motion + :extend t))) + "Highlight face for evil insert mode." + :group 'hl-line) + +(defface hl-line-visual + (list (list t (list :inherit 'hl-line :background azos/evil-color-visual + :extend t))) + "Highlight face for evil insert mode." + :group 'hl-line) + +(defface hl-line-operate + (list (list t (list :inherit 'hl-line :background azos/evil-color-operate + :extend t))) + "Highlight face for evil insert mode." + :group 'hl-line) + +(defun azos/hl-line-evil/set-hl-state (state-face) + "Refresh hl-line to be state-face" + (progn + (global-hl-line-unhighlight) + (setq-local hl-line-face state-face) + (global-hl-line-highlight))) +#+end_src + +#+begin_src emacs-lisp +(add-hook 'evil-insert-state-entry-hook + (lambda () (azos/hl-line-evil/set-hl-state 'hl-line-insert))) +(add-hook 'evil-normal-state-entry-hook + (lambda () (azos/hl-line-evil/set-hl-state 'hl-line-normal))) +(add-hook 'evil-emacs-state-entry-hook + (lambda () (azos/hl-line-evil/set-hl-state 'hl-line-emacs))) +(add-hook 'evil-replace-state-entry-hook + (lambda () (azos/hl-line-evil/set-hl-state 'hl-line-replace))) +(add-hook 'evil-motion-state-entry-hook + (lambda () (azos/hl-line-evil/set-hl-state 'hl-line-motion))) +(add-hook 'evil-visual-state-entry-hook + (lambda () (azos/hl-line-evil/set-hl-state 'hl-line-visual))) +(add-hook 'evil-operate-state-entry-hook + (lambda () (azos/hl-line-evil/set-hl-state 'hl-line-operate))) +#+end_src + +*** Line wrap + +Don't want to have to scroll to see more chars. + +#+begin_src emacs-lisp +(global-visual-line-mode t) +#+end_src + +*** Parenthesis + +Highlight matching parenthesis + +#+begin_src emacs-lisp +(show-paren-mode 1) +#+end_src + +*** Tabs + +Using spaces instead of tabs, default offset is 4. + +#+begin_src emacs-lisp +(setq-default indent-tabs-mode nil + tab-width 4 + c-basic-offset 4 + tab-always-indent 'complete) +#+end_src + +*** BIDI and lang + +Setting up Hebrew as alternative input, using bidi mode so that every line is +aligned left\right accordingly. + +#+begin_src emacs-lisp +(setq-default default-input-method "hebrew" + bidi-display-reordering t + bidi-paragraph-direction 'nil) + +(defun azos/set-bidi-env () + (setq bidi-paragraph-direction 'nil) +) + +(define-key azos/global-minor-mode/keymap + (kbd "C-SPC") 'toggle-input-method) +#+end_src + +*** Whitespace mode + +We define a custom global-whitespace-mode in order to enable it only on +relevant modes. + +We check if the current mode doesn't derive from a set of blacklisted mode, the +main culprit being terminal modes where whitespace occur naturally and are a +pain to see all the time. + +#+begin_src emacs-lisp +(setq-default whitespace-style + '(face tabs trailing tab-mark + lines-tail indentation)) + +(defun azos/whitespace-mode-func () + (interactive) + (if (derived-mode-p 'text-mode 'prog-mode 'org-mode) + (whitespace-mode 1) (whitespace-mode -1))) + +(add-hook 'after-change-major-mode-hook 'azos/whitespace-mode-func) +#+end_src + +*** Commenter + +Quick keybindings to comment out regions. + +#+begin_src emacs-lisp +(use-package evil-nerd-commenter + :config + (define-key evil-normal-state-map (kbd "C-;") + 'evilnc-comment-or-uncomment-lines)) +#+end_src + +*** Company mode + +Auto completion framework. + +#+begin_src emacs-lisp +(use-package company + :ensure t + :defer t + :init (add-hook 'after-init-hook 'global-company-mode) + :config + ;; (use-package company-irony :ensure t :defer t) + (setq + company-minimum-prefix-length 2 + company-show-numbers t + company-tooltip-limit 20 + company-idle-delay 0.2 + ) + :bind ("C-;" . company-complete-common) + ;; :hook (irony-mode . company-mode) + ) +#+end_src + +*** Folding + +#+begin_src emacs-lisp +(add-hook 'prog-mode-hook 'hs-minor-mode) +#+end_src + +* Mode specific +** Undo tree + +Loading =undo-tree= for undo/redo functionality with evil. + +Redo taken from https://github.com/syl20bnr/spacemacs/issues/14036 + +#+begin_src emacs-lisp +(use-package undo-tree + :after evil + :config + (evil-set-undo-system 'undo-tree) + (setq undo-tree-history-directory-alist + (list (cons "." (concat user-emacs-directory "undo-tree")))) + (global-undo-tree-mode 1) +) +#+end_src + +** Projectile + +Startup up projectile. + +A config line here disables modeline display because I don't want my modeline to be cluttered. + +Mapping modeline commands to =M-p= prefix. Also adding a shortcut to add project. + +#+begin_src emacs-lisp +(use-package projectile + :config + (projectile-mode +1) + (setq projectile-mode-line-function (lambda () "")) + :bind + (:map projectile-command-map + ("a" . projectile-add-known-project) + ) + (:map azos/global-minor-mode/keymap + ("M-p" . projectile-command-map)) +) +#+end_src + +Ivy for projectile: +Parts taken from [[https://emacs.stackexchange.com/questions/40787/display-corresponding-key-binding-of-command-during-m-x-completion][this post]] and [[https://emacs.stackexchange.com/questions/38841/counsel-m-x-always-shows][this post]] from StackOverflow. + +Helps with many functions to use counsel's/ivy's autocomplete with projectile. + +#+begin_src emacs-lisp +(use-package counsel-projectile + :after counsel projectile + :config + (counsel-projectile-mode +1) + (setq projectile-completion-system 'ivy) + ;Making counsel start with empty regex + (when (commandp 'counsel-M-x) + (global-set-key [remap execute-extended-command] 'counsel-M-x)) + (setcdr (assoc 'counsel-M-x ivy-initial-inputs-alist) "") +) +#+end_src + +** Tramp + +Ensuring tramp is loaded, and loading counsel-tramp for easy tramping. + +#+begin_src emacs-lisp +(use-package tramp + :straight (:type built-in)) + +(use-package counsel-tramp) +#+end_src + +** Dired + +Need to autoload dired-x for dired-omit + +#+begin_src emacs-lisp +;; (autoload 'dired-omit-mode "dired-x") +(setq dired-omit-files "^\\...+$") +(add-hook 'dired-mode-hook 'dired-omit-mode) +(add-hook 'dired-mode-hook 'dired-hide-details-mode) +(evil-collection-dired-setup) +#+end_src + +#+begin_src emacs-lisp +(use-package dired-subtree + :config + (evil-collection-define-key 'normal 'dired-mode-map + (kbd "SPC") 'dired-subtree-toggle + (kbd "TAB") 'dired-subtree-cycle + ) + (setq dired-subtree-use-backgrounds nil) + ;Evil collection binds these keys, we need them for window movement + (evil-collection-define-key 'normal 'dired-mode-map + (kbd "M-j") nil + (kbd "M-k") nil) +) + +#+end_src + +** Magit + +#+begin_src emacs-lisp +(use-package magit + :config + (evil-collection-magit-setup) + :bind + (:map anerenv/global-minor-mode/open-keymap + ("g" . 'magit-status)) +) +#+end_src + +** Org +*** Base + +#+begin_src emacs-lisp +(require 'org-faces) +(defun anerenv/set-org-mode-fixed-pitch-faces () + (mapc (lambda (face) (set-face-attribute face nil + :font (face-attribute 'fixed-pitch :font) + :height (face-attribute 'fixed-pitch :height))) + `(line-number + org-block + org-special-keyword + org-drawer + org-todo + org-done + org-priority + org-checkbox + org-block-end-line + org-block-begin-line + org-table + org-verbatim))) + +(use-package org + :hook + (org-mode . variable-pitch-mode) + (org-mode . anerenv/set-bidi-env) + (org-mode . (lambda () + (setq-local whitespace-style '(face tabs trailing tab-mark + indentation)))) + :config + (anerenv/set-org-mode-fixed-pitch-faces) + (setq org-src-tab-acts-natively t + org-adapt-indentation nil + org-startup-folded t + org-hide-emphasis-markers t) + (set-face-attribute 'org-code nil + :family (face-attribute 'fixed-pitch :family)) + (set-face-attribute 'org-block nil + :family (face-attribute 'fixed-pitch :family)) + :bind + ("C-a" . nil) + ("C-a l" . org-toggle-latex-fragment) +) +#+end_src + +#+end_src +*** Code blocks + +The following displays the contents of code blocks in Org-mode files using +the major-mode of the code. It also changes the behavior of TAB to as if it +were used in the appropriate major mode. + +#+begin_src emacs-lisp +(setq org-src-fontify-natively t + org-src-tab-acts-natively t + org-src-preserve-indentation t) + +(set-face-attribute 'org-block nil + :background "LemonChiffon1") +(set-face-attribute 'org-block-begin-line nil + :background "LightYellow2") +(set-face-attribute 'org-block-end-line nil + :background "LightYellow2") +#+end_src + +*** Babel + +Define languages to use + +#+begin_src emacs-lisp +(require 'ob) +(require 'ob-tangle) + +;; TODO Not sure I like this here +(org-babel-do-load-languages + 'org-babel-load-languages + '((shell . t) + (emacs-lisp . t) + (python . t) + (org . t) + (lilypond . t) + (latex . t) + (js . t) + (java . t) + (dot . t) + (C . t))) + +;; TODO move these around +;; (add-to-list 'org-src-lang-modes (quote ("dot". graphviz-dot))) +;; (add-to-list 'org-src-lang-modes (quote ("plantuml" . fundamental))) +;; (add-to-list 'org-babel-tangle-lang-exts '("clojure" . "clj")) +#+end_src + +This section makes code-indentation correction work inside source blocks. +Taken from: https://github.com/emacs-evil/evil/issues/1288 + +#+begin_src emacs-lisp +(defun anerenv/org/evil-org-insert-state-in-edit-buffer (fun &rest args) + "Bind `evil-default-state' to `insert' before calling FUN with ARGS." + (let ((evil-default-state 'insert) + ;; Force insert state + evil-emacs-state-modes + evil-normal-state-modes + evil-motion-state-modes + evil-visual-state-modes + evil-operator-state-modes + evil-replace-state-modes) + (apply fun args) + (evil-refresh-cursor))) + +(advice-add 'org-babel-do-key-sequence-in-edit-buffer + :around #'anerenv/org/evil-org-insert-state-in-edit-buffer) +#+end_src + +* Provide + +#+begin_src emacs-lisp +(provide 'azos-emacs-base) +#+end_src +