diff options
| -rw-r--r-- | .bashrc | 60 | ||||
| -rw-r--r-- | doom/config.el | 344 | ||||
| -rw-r--r-- | doom/init.el | 18 | ||||
| -rw-r--r-- | doom/packages.el | 8 | ||||
| -rw-r--r-- | tmux/.tmux.conf | 90 |
5 files changed, 505 insertions, 15 deletions
@@ -0,0 +1,60 @@ +# .bashrc + +# Custom prompt with directory in #afd7ff +PS1='[\u@\h \[\e[38;2;175;215;255m\]\w\[\e[0m\]]\$ ' + +# Aliases +alias python=python3 +alias ls='ls -larth' +alias e='emacsclient -nc -a ""' +alias ke='emacsclient -e "(kill-emacs)"' +alias copy='xclip -selection clipboard' +alias paste='xclip -o -selection clipboard' + +# bun completions +[ -s "$HOME/.bun/_bun" ] && source "$HOME/.bun/_bun" + +# bun +export BUN_INSTALL="$HOME/.bun" +export PATH="$BUN_INSTALL/bin:$PATH" + +# Local bins +export PATH="$HOME/.local/bin:$PATH" +# Doom Emacs CLI +export PATH="$HOME/.config/emacs/bin:$PATH" + +# Auto-attach or create tmux session on shell start +if [ -z "$TMUX" ]; then + tmux attach 2>/dev/null || tmux new -s main +fi + +# Source global definitions +if [ -f /etc/bashrc ]; then + . /etc/bashrc +fi + +# User specific environment +if ! [[ "$PATH" =~ "$HOME/.local/bin:$HOME/bin:" ]]; then + PATH="$HOME/.local/bin:$HOME/bin:$PATH" +fi +export PATH + +# User specific aliases and functions +if [ -d ~/.bashrc.d ]; then + for rc in ~/.bashrc.d/*; do + if [ -f "$rc" ]; then + . "$rc" + fi + done +fi +unset rc + +[ -f "$HOME/.cargo/env" ] && . "$HOME/.cargo/env" + +# pnpm +export PNPM_HOME="/home/yousefjan/.local/share/pnpm" +case ":$PATH:" in + *":$PNPM_HOME:"*) ;; + *) export PATH="$PNPM_HOME:$PATH" ;; +esac +# pnpm end diff --git a/doom/config.el b/doom/config.el index 567cc2a..f9a039b 100644 --- a/doom/config.el +++ b/doom/config.el @@ -71,7 +71,7 @@ ;; If you use `org' and don't want your org files in the default location below, ;; change `org-directory'. It must be set before org loads! -(setq org-directory "~/org/") +(setq org-directory "~/Documents/notes/") ;; Keep terminal and editor typography aligned and ensure Nerd Font glyphs render. (setq doom-font (font-spec :family "FiraCode Nerd Font Mono" :size 15) @@ -305,16 +305,346 @@ ;; Move visual-line selection up/down with J/K; preserve original behavior in other visual modes (map! :v "J" (cmd! (if (eq evil-visual-selection 'line) - (drag-stuff-down 1) - (evil-join (region-beginning) (region-end)))) + (drag-stuff-down 1) + (evil-join (region-beginning) (region-end)))) :v "K" (cmd! (if (eq evil-visual-selection 'line) - (drag-stuff-up 1) - (evil-lookup)))) + (drag-stuff-up 1) + (evil-lookup)))) -;; Use ROCm's bundled clangd for C/C++ (HIP) — same LLVM toolchain as hipcc, -;; so it understands hip/hip_runtime.h and hip* types via compile_commands.json. (after! lsp-clangd (setq lsp-clients-clangd-executable "/usr/lib64/rocm/llvm/bin/clangd" lsp-clients-clangd-args '("--header-insertion=never" "--background-index" "--compile-commands-dir=."))) + + +(after! lsp-mode + (setq lsp-idle-delay 0.5 + lsp-log-io nil + lsp-completion-provider :capf + lsp-completion-enable t + lsp-enable-file-watchers nil + lsp-auto-guess-root t + lsp-enable-folding nil + lsp-enable-text-document-color nil + lsp-enable-on-type-formatting nil + lsp-enable-snippet t + lsp-enable-symbol-highlighting nil + lsp-enable-links nil + lsp-restart 'auto-restart + lsp-keep-workspace-alive nil + ;; Go / gopls + lsp-go-hover-kind "FullDocumentation" + lsp-go-analyses '((nilness . t) + (unusedwrite . t) + (unusedparams . t)) + lsp-gopls-completeUnimported t + lsp-gopls-staticcheck t + lsp-gopls-use-placeholders t + lsp-gopls-analyses '((unusedparams . t) + (unusedwrite . t) + (nilness . t)))) + +(after! lsp-ui + (setq lsp-ui-doc-enable t + lsp-ui-doc-position 'at-point + lsp-ui-doc-max-height 8 + lsp-ui-doc-max-width 72 + lsp-ui-doc-show-with-cursor t + lsp-ui-doc-delay 0.5 + lsp-ui-sideline-enable nil + lsp-ui-peek-enable t)) + +;; Attach LSP to Go tree-sitter modes too (harmless if those modes never load) +(add-hook 'go-ts-mode-hook #'lsp-deferred) +(add-hook 'go-mod-ts-mode-hook #'lsp-deferred) + +;;; --- Project detection (go/rust/node/python, fall back to .git) ----------- +(after! project + (add-hook 'project-find-functions + (lambda (dir) + (cond + ((locate-dominating-file dir "go.mod") + (cons 'transient (locate-dominating-file dir "go.mod"))) + ((locate-dominating-file dir "Cargo.toml") + (cons 'transient (locate-dominating-file dir "Cargo.toml"))) + ((locate-dominating-file dir "package.json") + (cons 'transient (locate-dominating-file dir "package.json"))) + ((or (locate-dominating-file dir "pyproject.toml") + (locate-dominating-file dir "setup.py") + (locate-dominating-file dir "requirements.txt")) + (cons 'transient (or (locate-dominating-file dir "pyproject.toml") + (locate-dominating-file dir "setup.py") + (locate-dominating-file dir "requirements.txt")))) + ((locate-dominating-file dir ".git") + (cons 'transient (locate-dominating-file dir ".git"))))))) + +(with-eval-after-load 'treesit + (setq treesit-language-source-alist + '((go "https://github.com/tree-sitter/tree-sitter-go" "master" "src") + (gomod "https://github.com/camdencheek/tree-sitter-go-mod" "main" "src") + (javascript "https://github.com/tree-sitter/tree-sitter-javascript" "master" "src") + (typescript "https://github.com/tree-sitter/tree-sitter-typescript" "master" "typescript/src") + (tsx "https://github.com/tree-sitter/tree-sitter-typescript" "master" "tsx/src") + (html "https://github.com/tree-sitter/tree-sitter-html" "master" "src") + (css "https://github.com/tree-sitter/tree-sitter-css" "master" "src") + (templ "https://github.com/vrischmann/tree-sitter-templ" "master" "src")))) + +(defun jb/install-treesit-grammars () + "Install any missing tree-sitter grammars in `treesit-language-source-alist'." + (interactive) + (require 'treesit) + (dolist (lang '(go gomod javascript typescript tsx html css templ)) + (unless (treesit-language-available-p lang) + (message "Installing grammar for %s..." lang) + (treesit-install-language-grammar lang))) + (message "Tree-sitter grammar installation complete!")) + +;; Let org-babel source edits use the tree-sitter major modes +(after! org + (setq org-src-lang-modes + (append org-src-lang-modes + '(("go" . go-ts) + ("javascript" . js-ts) + ("typescript" . typescript-ts) + ("html" . html-ts) + ("css" . css-ts))))) + +;;; --- Emmet ---------------------------------------------------------------- +(add-hook 'sgml-mode-hook #'emmet-mode) +(add-hook 'css-mode-hook #'emmet-mode) +(setq emmet-expand-jsx-className? nil) +(after! emmet-mode + (map! :map emmet-mode-keymap + :n "<C-return>" #'emmet-expand-line)) + +;;; --- vterm ---------------------------------------------------------------- +(setq vterm-environment '("TERM=xterm-256color")) +(set-language-environment "UTF-8") +(set-default-coding-systems 'utf-8) + +(after! vterm + (setq vterm-buffer-name-string "vterm %s") + + ;; Open vterm in the directory of the current buffer / dired location + (defadvice! +vterm-use-current-directory-a (fn &rest args) + "Make `vterm' open in the directory of the current buffer." + :around #'vterm + (let ((default-directory (or (and (buffer-file-name) + (file-name-directory (buffer-file-name))) + (and (eq major-mode 'dired-mode) + (dired-current-directory)) + default-directory))) + (apply fn args))) + + (defadvice! +vterm-use-current-directory-b (fn &rest args) + "Make Doom's `+vterm/here' open in the directory of the current buffer." + :around #'+vterm/here + (let ((default-directory (or (and (buffer-file-name) + (file-name-directory (buffer-file-name))) + (and (eq major-mode 'dired-mode) + (dired-current-directory)) + default-directory))) + (apply fn args)))) + +(defun open-vterm-in-current-context () + "Open vterm in the context of the current buffer/window." + (interactive) + (when-let ((buf (current-buffer))) + (with-current-buffer buf + (call-interactively #'+vterm/here)))) + +(after! magit + (defun my/quick-commit-push () + "Stage all, commit with a prompted message, and push to origin." + (interactive) + (let ((msg (read-string "Commit message: "))) + (magit-call-git "add" "-A") + (magit-call-git "commit" "-m" msg) + (magit-call-git "push" "--set-upstream" "origin" (magit-get-current-branch)) + (message "Committed and pushed: %s" msg)))) + +;; Additive: keep Doom's full SPC g menu, just add quick commit+push on SPC g z +(map! :leader + :desc "Quick commit & push" "g z" #'my/quick-commit-push) + +(after! tramp + (setq tramp-default-method "ssh" + tramp-verbose 1 + tramp-use-ssh-controlmaster-options nil + tramp-chunksize 500 + tramp-connection-timeout 10 + remote-file-name-inhibit-cache nil + tramp-cache-read-persistent-data t) + (setq vc-ignore-dir-regexp + (format "%s\\|%s" vc-ignore-dir-regexp tramp-file-name-regexp))) + + +(after! treemacs + (setq treemacs-position 'left + treemacs-display-in-side-window t + treemacs-width 35)) + + +(defvar my/notes-dir (file-name-as-directory (expand-file-name "~/Documents/notes")) + "Root directory for org notes, agenda, and capture files.") + +;;; --- Org core: habits, logging, auto-clock on STRT ----------------------- +(after! org + (setq org-modules '(org-habit) + org-log-done 'time + org-clock-out-when-done nil) + ;; Promote/demote with M-left/right in normal state + (map! :map org-mode-map + :n "<M-left>" #'org-do-promote + :n "<M-right>" #'org-do-demote)) + +;; Auto clock-in when a task enters STRT (a Doom default keyword), out when it leaves +(defun my/org-clock-in-if-starting () + "Clock in when the task state changes to STRT." + (when (and (string= org-state "STRT") + (not (org-clock-is-active))) + (org-clock-in))) +(defun my/org-clock-out-if-not-starting () + "Clock out when leaving the STRT state." + (when (and (org-clock-is-active) + (not (string= org-state "STRT"))) + (org-clock-out))) +(add-hook 'org-after-todo-state-change-hook #'my/org-clock-in-if-starting) +(add-hook 'org-after-todo-state-change-hook #'my/org-clock-out-if-not-starting) + +;;; --- Org agenda: time grid + "Dashboard" custom view --------------------- +(after! org + (setq org-agenda-time-grid + '((daily today require-timed) + (500 600 700 800 900 1000 1100 1200 + 1300 1400 1500 1600 1700 1800 1900 2000 2100) + " " "────────────────") + org-agenda-current-time-string + "<── NOW ────────────────────────────────────────" + org-habit-show-habits-only-for-today t + org-habit-graph-column 50 + org-agenda-remove-tags t + org-agenda-block-separator ?─ + org-agenda-custom-commands + '(("d" "Dashboard" + ((tags "PRIORITY=\"A\"" + ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done)) + (org-agenda-overriding-header "\nPRIORITY\n") + (org-agenda-prefix-format " %?-12t %s"))) + (agenda "" + ((org-agenda-start-day "+0d") + (org-agenda-span 1) + (org-agenda-remove-tags t) + (org-agenda-todo-keyword-format "") + (org-agenda-scheduled-leaders '("" "")) + (org-agenda-overriding-header "\nTODAY\n") + (org-agenda-prefix-format " %?-12t %s"))) + (tags-todo "-STYLE=\"habit\"" + ((org-agenda-overriding-header "\ALL TASKS\n") + (org-agenda-sorting-strategy '(priority-down)) + (org-agenda-remove-tags t) + (org-agenda-prefix-format " %?-12t %s")))))))) + +(defun my/org-agenda-dashboard () + "Open the custom org-agenda dashboard." + (interactive) + (org-agenda nil "d")) +(map! :leader :desc "Org dashboard" "o A" #'my/org-agenda-dashboard) + +;;; --- Capture templates (paths under my/notes-dir) ------------------------ +(after! org + (setq org-capture-templates + `(("t" "Todo" entry + (file+headline ,(concat my/notes-dir "inbox.org") "Inbox") + "* TODO %^{Task}\n:PROPERTIES:\n:CREATED: %U\n:CAPTURED: %a\n:END:\n%?") + ("n" "Note" entry + (file+headline ,(concat my/notes-dir "notes.org") "Inbox") + "* [%<%Y-%m-%d %a>] %^{Title}\n:PROPERTIES:\n:CREATED: %U\n:CAPTURED: %a\n:END:\n%?" + :prepend t) + ("e" "Event" entry + (file+headline ,(concat my/notes-dir "calendar.org") "Events") + "* %^{Event}\n%^{SCHEDULED}T\n:PROPERTIES:\n:CREATED: %U\n:END:\n%?") + ("d" "Deadline" entry + (file+headline ,(concat my/notes-dir "calendar.org") "Deadlines") + "* TODO %^{Task}\nDEADLINE: %^{Deadline}T\n:PROPERTIES:\n:CREATED: %U\n:END:\n%?")))) + +(use-package! org-roam + :defer t + :commands (org-roam-node-find + org-roam-node-insert + org-roam-dailies-goto-today + org-roam-buffer-toggle + org-roam-db-sync + org-roam-capture) + :init + (setq org-roam-directory (concat my/notes-dir "roam") + org-roam-database-connector 'sqlite-builtin + org-roam-db-location (expand-file-name "org-roam.db" (concat my/notes-dir "roam")) + org-roam-v2-ack t) + :config + (setq org-roam-db-update-on-save nil + org-roam-completion-everywhere t) + (unless (file-exists-p org-roam-directory) + (make-directory org-roam-directory t)) + (add-hook 'org-roam-find-file-hook + (lambda () + (unless org-roam-db-autosync-mode + (org-roam-db-autosync-mode 1)))) + (setq org-roam-capture-templates + '(("d" "default" plain "%?" + :target (file+head "${slug}.org" + ":PROPERTIES:\n:ID: %(org-id-new)\n:END:\n#+title: ${title}\n#+filetags: \n\n") + :unnarrowed t) + ("c" "concept" plain "%?" + :target (file+head "concepts/${slug}.org" + ":PROPERTIES:\n:ID: %(org-id-new)\n:END:\n#+title: ${title}\n#+filetags: :concept:\n\n") + :unnarrowed t) + ("b" "book" plain "%?" + :target (file+head "books/${slug}.org" + ":PROPERTIES:\n:ID: %(org-id-new)\n:END:\n#+title: ${title}\n#+author: \n#+filetags: :book:\n\n* Summary\n\n* Key Ideas\n\n* Quotes\n\n* Related\n\n") + :unnarrowed t) + ("p" "person" plain "%?" + :target (file+head "people/${slug}.org" + ":PROPERTIES:\n:ID: %(org-id-new)\n:END:\n#+title: ${title}\n#+filetags: :person:\n\n* Background\n\n* Key Ideas\n\n* Works\n\n") + :unnarrowed t) + ("P" "project" plain "%?" + :target (file+head "projects/${slug}.org" + ":PROPERTIES:\n:ID: %(org-id-new)\n:END:\n#+title: ${title}\n#+filetags: :project:\n\n* Overview\n\n* Goals\n\n* Status\n\n* Notes\n\n") + :unnarrowed t))) + (setq org-roam-dailies-directory "daily/" + org-roam-dailies-capture-templates + '(("d" "default" entry "* %<%H:%M>: %?" + :target (file+head "%<%Y-%m-%d>.org" + ":PROPERTIES:\n:ID: %(org-id-new)\n:END:\n#+title: %<%Y-%m-%d %A>\n#+filetags: :daily:\n\n"))))) + +(use-package! org-roam-ui + :commands (org-roam-ui-mode org-roam-ui-open) + :after org-roam + :config + (setq org-roam-ui-sync-theme t + org-roam-ui-follow t + org-roam-ui-update-on-save t + org-roam-ui-open-on-start nil)) + +(defun my/org-insert-image () + "Select and insert an image into the current org file." + (interactive) + (let ((file (read-file-name "Select image: " "~/Pictures/" nil t))) + (when file + (insert (format "[[file:%s]]\n" file)) + (org-display-inline-images)))) +(after! org + (map! :map org-mode-map :localleader "I" #'my/org-insert-image)) + +(use-package! calfw + :commands (cfw:open-calendar-buffer) + :config (require 'calfw-org)) +(use-package! calfw-org + :commands (cfw:open-org-calendar) + :after (calfw org)) +(defun +calendar/open-calfw () + (interactive) + (require 'calfw-org) + (cfw:open-org-calendar)) +(map! :leader :desc "Calendar (calfw)" "o c" #'+calendar/open-calfw) diff --git a/doom/init.el b/doom/init.el index a46cdf5..107324e 100644 --- a/doom/init.el +++ b/doom/init.el @@ -43,7 +43,7 @@ ;;neotree ; a project drawer, like NERDTree for vim ophints ; highlight the region an operation acts on (popup +defaults) ; tame sudden yet inevitable temporary windows - tabs ; a tab bar for Emacs + ;;tabs ; a tab bar for Emacs treemacs ; a project drawer, like neotree but cooler unicode ; extended unicode support for various languages (vc-gutter +pretty) ; vcs diff in the fringe @@ -67,7 +67,7 @@ ;;word-wrap ; soft wrapping with language-aware indent :emacs - dired ; making dired pretty [functional] + (dired +dirvish) ; making dired pretty [functional] electric ; smarter, keyword-based electric-indent ;;eww ; the internet is gross ;;ibuffer ; interactive buffer management @@ -77,8 +77,8 @@ :term ;;eshell ; the elisp shell that works everywhere ;;shell ; simple shell REPL for Emacs - term ; basic terminal emulator for Emacs - ;;vterm ; the best terminal emulation in Emacs + ;;term ; basic terminal emulator for Emacs + vterm ; the best terminal emulation in Emacs :checkers syntax ; tasing you for every semicolon you forget @@ -96,11 +96,11 @@ ein ; tame Jupyter notebooks with emacs (eval +overlay) ; run code, run (also, repls) lookup ; navigate your code and its documentation - lsp ; M-x vscode + (lsp +peek) ; M-x vscode magit ; a git porcelain for Emacs make ; run make tasks from Emacs ;;pass ; password manager for nerds - pdf ; pdf enhancements + ;;pdf ; pdf enhancements ;;prodigy ; FIXME managing external services & code builders ;;terraform ; infrastructure as code ;;tmux ; an API for interacting with tmux @@ -178,7 +178,7 @@ :email ;;(mu4e +org +gmail) -;;notmuch + ;;notmuch ;;(wanderlust +gmail) :app @@ -189,5 +189,7 @@ ;;(rss +org) ; emacs as an RSS reader :config - ;;literate ; disabled: no config.org; tangle hook kill-emacs 3 aborted 'doom sync' + ;;literate ; disabled: no config.org (default +bindings +smartparens)) + +;; sync-trigger diff --git a/doom/packages.el b/doom/packages.el index b3322c7..de9ded0 100644 --- a/doom/packages.el +++ b/doom/packages.el @@ -47,3 +47,11 @@ ;; (unpin! pinned-package another-pinned-package) ;; ...Or *all* packages (NOT RECOMMENDED; will likely break things) ;; (unpin! t) + + +;;; ---------------------------------------------------------------------------- +;;; Phase 2 — notetaking (org-roam graph UI + calfw calendar over org agenda) +;;; ---------------------------------------------------------------------------- +(package! org-roam-ui) +(package! calfw) +(package! calfw-org) diff --git a/tmux/.tmux.conf b/tmux/.tmux.conf new file mode 100644 index 0000000..3361de2 --- /dev/null +++ b/tmux/.tmux.conf @@ -0,0 +1,90 @@ +set -g mouse on + + +setw -g mode-style 'fg=black bg=blue bold' +setw -g clock-mode-colour yellow + +set -g pane-border-style 'fg=red' +set -g pane-active-border-style 'fg=yellow' + +set -g status-position bottom +set -g status-justify left +set -g status-style 'fg=red' +set -g status-left '' +set -g status-left-length 30 + +setw -g window-status-current-style 'fg=black bg=blue' +setw -g window-status-current-format ' #I #W #F ' + +setw -g window-status-style 'fg=red bg=black' +setw -g window-status-format ' #I #[fg=white]#W #[fg=yellow]#F ' + +setw -g window-status-bell-style 'fg=yellow bg=red bold' + +set -g message-style 'fg=yellow bg=red bold' + +set -g status-justify centre + + + +set-option -g prefix 'C-a' + +set -g history-limit 1000000 + +bind-key J resize-pane -D 5 +bind-key K resize-pane -U 5 +bind-key H resize-pane -L 5 +bind-key L resize-pane -R 5 + +bind h select-pane -L +bind j select-pane -D +bind k select-pane -U +bind l select-pane -R + + +bind-key v split-window -v -c "#{pane_current_path}" +bind-key s split-window -h -c "#{pane_current_path}" + +setw -g mode-keys vi + +set-option -g status-right "" + +set -g base-index 1 + +bind r source-file ~/.tmux.conf \; display "Reloaded!" + +unbind -T copy-mode-vi Enter +unbind -T copy-mode-vi Space + +bind-key -T edit-mode-vi Up send-keys -X history-up +bind-key -T edit-mode-vi Down send-keys -X history-down + +bind-key -T copy-mode-vi 'v' send-keys -X begin-selection + +bind-key -T copy-mode-vi 'y' send -X copy-selection-and-cancel +set -ga terminal-overrides ',*:Ss=\E[%p1%d q:Se=\E[2 q' + +set -g default-terminal "tmux-256color" +set -as terminal-features ",xterm-ghostty:RGB" + + +bind-key y display-popup -d '#{pane_current_path}' -x R -h 95% -w 95% -E "emacsclient -t -a '' ." +bind-key g popup -E -w 95% -h 95% -d '#{pane_current_path}' lazygit + +set -g allow-passthrough on +set -ga update-environment TERM +set -ga update-environment TERM_PROGRAM + +bind c new-window -c "#{pane_current_path}" + +bind-key z popup -E -w 95% -h 90% + + +set -q -g status-utf8 on +setw -q -g utf8 on + +set -s escape-time 50 + +set -g focus-events on + +bind-key e display-popup -w 95% -h 90% -E "tmux capture-pane -Jp -S- > /tmp/tmux-scrollback && emacsclient -t -a '' /tmp/tmux-scrollback" |