parent
43fa5a76e2
commit
aefe49ed88
@ -0,0 +1,121 @@ |
||||
;; base.el |
||||
;; Configure emacs-builtins and core key bindings |
||||
;; |
||||
;; Emacs has a lot of things built-in that are disabled by default. |
||||
;; This module enables these settings, to create an editor experience |
||||
;; that I find more pleasing. If you want to get a taste of what it |
||||
;; is to use "kookie emacs", start by including this file. |
||||
;; |
||||
;; |
||||
;; This file is part of LIBKOOKIE, a collection of nix expressions. |
||||
;; LIBKOOKIE is licensed under the GPL-3.0 (or later) -- see LICENSE |
||||
|
||||
(provide 'base) |
||||
|
||||
;;; Setup consistent line numbering |
||||
(setq display-line-numbers-grow-only t) |
||||
(setq display-line-numbers-width-start t) |
||||
(global-display-line-numbers-mode t) |
||||
|
||||
;;; Use spaces instead of tabs |
||||
(setq tab-width 2) |
||||
(setq-default indent-tabs-mode nil) |
||||
(defvaralias 'c-basic-offset 'tab-width) |
||||
(defvaralias 'cperl-indent-level 'tab-width) |
||||
|
||||
;;; Hide startup splash |
||||
;; FIXME: this doesn't currently work... |
||||
(setq inhibit-startup-screen t) |
||||
(setq inhibit-splash-screen t) |
||||
(setq initial-scratch-message nil) |
||||
|
||||
;;; Delete selections |
||||
(delete-selection-mode t) |
||||
|
||||
;;; Display and create symbol pairs |
||||
(show-paren-mode t) |
||||
(electric-pair-mode t) |
||||
|
||||
;;; Don't soft-wrap lines |
||||
(setq-default truncate-lines t) |
||||
|
||||
;;; Hide default UI elements |
||||
(menu-bar-mode -1) |
||||
(tool-bar-mode -1) |
||||
(scroll-bar-mode -1) |
||||
|
||||
;;; Display column in the mode line |
||||
(column-number-mode t) |
||||
|
||||
;;; Enable ido mode |
||||
(ido-mode t) |
||||
(setq ido-enable-flex-matching t) |
||||
(setq ido-everywhere t) |
||||
|
||||
;;; Enable ruler-mode in all buffers |
||||
(add-hook 'find-file-hook (lambda () (ruler-mode 1))) |
||||
|
||||
;;; Setup mitosis buffer splitting |
||||
(setq emacs-anchor default-directory) |
||||
(defun mitosis () (interactive) (make-frame)) |
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||||
;;; Function definitions |
||||
;;; |
||||
;;; A set of functions to compliment emacs' builtin functionality, to |
||||
;;; create and navigate buffers. |
||||
|
||||
(defun new-empty-buffer () |
||||
"Opens a new empty buffer." |
||||
(interactive) |
||||
(let ((buf (generate-new-buffer "untitled"))) |
||||
(switch-to-buffer buf) |
||||
(funcall (and initial-major-mode)) |
||||
(setq buffer-offer-save t))) |
||||
|
||||
(defun user-buffer-q () |
||||
"Check if a buffer is a user buffer" |
||||
(interactive) |
||||
(if (string-equal "*" (substring (buffer-name) 0 1)) |
||||
nil |
||||
(if (string-equal major-mode "dired-mode") |
||||
nil |
||||
t |
||||
))) |
||||
|
||||
(defun next-user-buffer () |
||||
"Switch to the next user buffer." |
||||
(interactive) |
||||
(next-buffer) |
||||
(let ((i 0)) |
||||
(while (< i 20) |
||||
(if (not (user-buffer-q)) |
||||
(progn (next-buffer) |
||||
(setq i (1+ i))) |
||||
(progn (setq i 100)))))) |
||||
|
||||
(defun previous-user-buffer () |
||||
"Switch to the previous user buffer." |
||||
(interactive) |
||||
(previous-buffer) |
||||
(let ((i 0)) |
||||
(while (< i 20) |
||||
(if (not (user-buffer-q)) |
||||
(progn (previous-buffer) |
||||
(setq i (1+ i))) |
||||
(progn (setq i 100)))))) |
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||||
;;; Key bindings |
||||
;;; |
||||
;;; Custom set of key bindings to augment emacs' builtins |
||||
|
||||
(global-set-key (kbd "C-x C-k") 'kill-current-buffer) |
||||
(global-set-key (kbd "C-x n") 'new-empty-buffer) |
||||
(global-set-key (kbd "C-<next>") 'next-user-buffer) |
||||
(global-set-key (kbd "C-<prior>") 'previous-user-buffer) |
||||
(global-set-key (kbd "M-s M-s") 'save-buffer) |
||||
(global-set-key (kbd "C-t") 'smex) |
||||
|
@ -0,0 +1,3 @@ |
||||
{ buildModule, pkgs, epkgs }: |
||||
with epkgs; |
||||
(buildModule "base" ./. [ smex ]) |
@ -0,0 +1,70 @@ |
||||
/** Build a meta-module that includes sub-modules |
||||
* |
||||
* Because of the way that the emacsWithPackages function works, it |
||||
* can only load a single "default.el" as an entry point. |
||||
* |
||||
*/ |
||||
|
||||
{ pkgs, lib, ... }: |
||||
|
||||
rec { |
||||
|
||||
/** |
||||
* Create a new elisp module with a set of package dependencies. |
||||
* |
||||
* { |
||||
* name = "base"; |
||||
* lisp = ./default.el; |
||||
* deps = [ pkgs.hello ]; |
||||
* } |
||||
* |
||||
* The lisp path is the main file contained in the nix store, and deps |
||||
* contains a set of emacsPackages, and base packages that the module |
||||
* depends on to function. |
||||
*/ |
||||
buildModule = with pkgs; (name: path: pkgs: { |
||||
inherit name pkgs; |
||||
path = runCommand "${name}.el" {} '' |
||||
mkdir -p $out/share/emacs/site-lisp |
||||
cp -r ${path}/default.el $out/share/emacs/site-lisp/${name}.el |
||||
''; |
||||
}); |
||||
|
||||
/** |
||||
* Build a bootstrap module which includes submodules |
||||
* |
||||
* |
||||
*/ |
||||
bootstrap = |
||||
modules: let |
||||
# Take a module and unfold the paths into a list |
||||
unfold = { path, pkgs, ... }: [ path ] ++ pkgs; |
||||
# Create an elisp require statement |
||||
mkInclude = modules: lib.concatMapStringsSep "\n" (name: "(require '${name})") modules; |
||||
# Build the list of module paths |
||||
mkModPaths = modules: builtins.foldl' (acc: mod: acc ++ (unfold mod)) [] modules; |
||||
# Build the list of module names |
||||
mkModList = modules: map (m: m.name) modules; |
||||
|
||||
### Function invocations |
||||
modList = mkModList modules; |
||||
modPaths = mkModPaths modules; |
||||
loader = pkgs.writeTextFile { |
||||
name = "default.el"; |
||||
text = '' |
||||
;;; THIS FILE IS AUTOMATICALLY GENERATED |
||||
${(mkInclude modList)} |
||||
''; |
||||
}; |
||||
loaderWrap = pkgs.runCommand "default.el" {} '' |
||||
mkdir -p $out/share/emacs/site-lisp/ |
||||
cp ${loader} $out/share/emacs/site-lisp/default.el |
||||
''; |
||||
paths = modPaths ++ [ loaderWrap ]; |
||||
in |
||||
with pkgs; |
||||
symlinkJoin { |
||||
name = "libkookie-emacs-packages"; |
||||
inherit paths; |
||||
}; |
||||
} |
@ -1,43 +1,50 @@ |
||||
{ stdenv, pkgs, ... }: |
||||
{ stdenv, lib, pkgs, ... } @ args: |
||||
|
||||
with pkgs; emacsWithPackages (epkgs: |
||||
(with epkgs; [ |
||||
(runCommand "init.el" {} '' |
||||
mkdir -p $out/share/emacs/site-lisp |
||||
cp ${./init.el} $out/share/emacs/site-lisp/default.el |
||||
'') |
||||
with (import ./builder.nix args); |
||||
pkgs.emacsWithPackages (epkgs: |
||||
let |
||||
include = path: (import path { inherit buildModule pkgs epkgs; }); |
||||
modules = [ ./base ./move-lines ./theme ]; |
||||
kookie-config = bootstrap (map (p: include p) modules); |
||||
in [ |
||||
kookie-config |
||||
]) |
||||
|
||||
# Language support |
||||
fish-mode |
||||
lsp-mode |
||||
# markdown-mode |
||||
nim-mode |
||||
nix-mode |
||||
protobuf-mode |
||||
python-mode |
||||
rust-mode |
||||
|
||||
color-identifiers-mode |
||||
color-theme-sanityinc-tomorrow |
||||
company |
||||
company-lsp |
||||
|
||||
|
||||
|
||||
# Language support |
||||
# fish-mode |
||||
# lsp-mode |
||||
# markdown-mode |
||||
# nim-mode |
||||
# nix-mode |
||||
# protobuf-mode |
||||
# python-mode |
||||
# rust-mode |
||||
|
||||
# color-identifiers-mode |
||||
# color-theme-sanityinc-tomorrow |
||||
# company |
||||
# company-lsp |
||||
# direnv |
||||
fzf |
||||
ido-vertical-mode |
||||
ledger-mode |
||||
lsp-ui |
||||
magit |
||||
monokai-theme |
||||
multiple-cursors |
||||
notmuch |
||||
org |
||||
protobuf-mode |
||||
scad-mode |
||||
smex |
||||
sublimity |
||||
treemacs |
||||
undo-tree |
||||
visual-fill-column |
||||
which-key |
||||
yasnippet |
||||
])) |
||||
# fzf |
||||
# ido-vertical-mode |
||||
# ledger-mode |
||||
# lsp-ui |
||||
# magit |
||||
# monokai-theme |
||||
# multiple-cursors |
||||
# notmuch |
||||
# org |
||||
# protobuf-mode |
||||
# scad-mode |
||||
# smex |
||||
# sublimity |
||||
# treemacs |
||||
# undo-tree |
||||
# visual-fill-column |
||||
# which-key |
||||
# yasnippet |
||||
# ])) |
||||
|
@ -0,0 +1,93 @@ |
||||
;; move-lines.el |
||||
;; Provide a mechanism to move line selections |
||||
;; |
||||
;; By default, moving lines up and down in a buffer is very annoying, |
||||
;; so this set of functions creates a way to do this, and binds it to |
||||
;; easily accessible key bindings. This mirrors functionality from |
||||
;; other GUI text editors such as sublime text or vs code. |
||||
;; |
||||
;; |
||||
;; This file is part of LIBKOOKIE, a collection of nix expressions. |
||||
;; LIBKOOKIE is licensed under the GPL-3.0 (or later) -- see LICENSE |
||||
|
||||
(provide 'move-lines) |
||||
|
||||
(defun move--section (offset) |
||||
"Move a line or reg up or down by on offset." |
||||
|
||||
;; We'll have to track 4 text points in this function |
||||
;; Future me: the * is important.... |
||||
(let* (txt-start |
||||
txt-end |
||||
(reg-start (point)) |
||||
(reg-end reg-start) |
||||
|
||||
;; De we delete a trailing \n |
||||
del-nl-trail) |
||||
|
||||
;; Find the text borders |
||||
(when (region-active-p) |
||||
(if (> (point) (mark)) |
||||
(setq reg-start (mark)) |
||||
(exchange-point-and-mark) |
||||
(setq reg-end (point)))) |
||||
(end-of-line) |
||||
|
||||
;; If point > point-max there is no trailing \n |
||||
(if (< (point) (point-max)) |
||||
(forward-char 1) |
||||
(setq del-nl-trail t) |
||||
(insert-char ?\n)) |
||||
(setq txt-end (point) |
||||
reg-end (- reg-end txt-end)) |
||||
|
||||
;; text/region start points |
||||
(goto-char reg-start) |
||||
(beginning-of-line) |
||||
(setq txt-start (point) |
||||
reg-start (- reg-start txt-end)) |
||||
|
||||
;; Fake the txt move |
||||
(let ((text (delete-and-extract-region txt-start txt-end))) |
||||
(forward-line offset) |
||||
(when (not (= (current-column) 0)) |
||||
(insert-char ?\n) |
||||
(setq del-nl-trail t)) |
||||
(insert text)) |
||||
|
||||
;; Restore point position |
||||
(forward-char reg-start) |
||||
|
||||
;; Clean that annoying \n at the end |
||||
(when del-nl-trail |
||||
(save-excursion |
||||
(goto-char (point-max)) |
||||
(delete-char -1))) |
||||
|
||||
;; If we operated on a region we need to fix the selection |
||||
(when (region-active-p) |
||||
(setq deactivate-mark nil) |
||||
(set-mark (+ (point) (- (- reg-start reg-end))))))) |
||||
|
||||
(defun move-section-up (offset) |
||||
"Move a line or reg upwards" |
||||
(interactive "p") |
||||
(if (eq offset nil) |
||||
setq offset 1) |
||||
(move--section (- offset))) |
||||
|
||||
(defun move-section-down (offset) |
||||
"Move a line or region dawnwards" |
||||
(interactive "p") |
||||
(if (eq offset nil) |
||||
setq offset 1) |
||||
(move--section offset)) |
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||||
;;; Key bindings |
||||
;;; |
||||
;;; Custom set of key bindings to augment emacs' builtins |
||||
|
||||
(global-set-key (kbd "C-M-<up>") 'move-section-up) |
||||
(global-set-key (kbd "C-M-<down>") 'move-section-down) |
@ -0,0 +1,2 @@ |
||||
{ buildModule, pkgs, epkgs }: |
||||
(buildModule "move-lines" ./. []) |
@ -0,0 +1,9 @@ |
||||
|
||||
(provide 'theme) |
||||
|
||||
(custom-set-variables |
||||
'(custom-safe-themes |
||||
'("628278136f88aa1a151bb2d6c8a86bf2b7631fbea5f0f76cba2a0079cd910f7d" default)) |
||||
'(send-mail-function 'sendmail-send-it)) |
||||
(custom-set-faces) |
||||
|
@ -0,0 +1,6 @@ |
||||
{ buildModule, pkgs, epkgs }: |
||||
with epkgs; |
||||
(buildModule "theme" ./. [ |
||||
color-theme-sanityinc-tomorrow |
||||
color-identifiers-mode |
||||
]) |
Loading…
Reference in new issue