Skip to content

Instantly share code, notes, and snippets.

@zkytony
Created July 5, 2021 14:18
Show Gist options
  • Save zkytony/006028d6871087e3e467d011070c6ae5 to your computer and use it in GitHub Desktop.
Save zkytony/006028d6871087e3e467d011070c6ae5 to your computer and use it in GitHub Desktop.
Some helpful lisp functions for emacs efficiency
;;; package --- Summary
;;;; Commentary:
;;; Code:
(require 'cl)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Note taking ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; All of these functions will prefix with 'eff' to mean "efficient"
(defvar eff-notes-repo-path nil)
(defvar eff-knowledge-path (concat eff-notes-repo-path
nil))
(defvar eff-kw-open-pdf-after-compile t)
(defvar eff-kw-compile_prefix "_auto_")
(defvar eff-kw-chapter-default nil)
(defvar eff-pyvenv-path "~/pyenv/py37")
(defun eff-pyenv-activate-command-string ()
"Return command string to activate python virtrual environment."
(concat
"source "
(concat
(file-name-as-directory eff-pyvenv-path) "bin/activate")))
(defun eff-sync-notes ()
"Pulls from master in the Notes repo."
(interactive)
(let (Notes-Repo-Path)
(setq Notes-Repo-Path (read-directory-name "Path to Notes repo: "
eff-notes-repo-path)) ; initial
(let ((output (shell-command-to-string ; this function returns shell command output in string
(concat
(concat "cd " Notes-Repo-Path) "; git pull origin master"))))
(message output))))
;; Functions related to Knowledge notes
;; Note on variable name: `catg` always means technical or nontechnical
(defun eff-kw-list-chapters (catg)
"Return list of chapter names under CATG (technical or nontechnical)."
(remove-if
(lambda (item)
"check if item is '.' or '..'"
(or (string= item ".")
(string= item "..")))
(directory-files (concat (file-name-as-directory eff-knowledge-path) catg))))
(defun eff-kw-read-chapter (catg)
"Return a chapter that the user types; The chapter can be\
existing under CATG (technical or nontechnical) or new."
(let (chapters
user-chapter)
(setq chapters (eff-kw-list-chapters catg))
(setq user-chapter (completing-read
"Chapter: "
chapters nil 'confirm
(if eff-kw-chapter-default
eff-kw-chapter-default
nil)))
(setq eff-kw-chapter-default user-chapter)
user-chapter))
(defun eff-kw-chapter-path (catg chapter)
"Return knowledge/CATG/CHAPTER."
(concat (file-name-as-directory eff-knowledge-path)
(concat (file-name-as-directory catg)
chapter)))
(defun eff-kw-list-tex-files (catg chapter)
"Return list of .tex files under CATG/CHAPTER."
(remove-if
(lambda (item)
"Check if it's tex file"
(or (not (string-suffix-p "tex" item))))
(directory-files (eff-kw-chapter-path catg chapter))))
(defun eff-kw-read-tex (catg chapter)
"Read tex file name under CATG/CHAPTER."
(interactive)
(let (tex-files
user-tex-file)
(setq tex-files (eff-kw-list-tex-files catg chapter))
(setq user-tex-file (completing-read
"Topic (.tex file): "
tex-files nil 'confirm))
user-tex-file))
(defun eff-add-knowledge-with-catg (catg)
"Add knowledge note under CATG."
(let (user-chapter
user-tex-file)
(setq user-chapter (eff-kw-read-chapter catg))
; create chapter, if wanted
(let ((chapter-path (eff-kw-chapter-path catg user-chapter)))
(unless (file-exists-p chapter-path)
(make-directory chapter-path :parents)))
(setq user-tex-file (eff-kw-read-tex catg user-chapter))
; open up the tex file
(switch-to-buffer (find-file-noselect
(concat
(file-name-as-directory (eff-kw-chapter-path catg user-chapter))
user-tex-file)))
; opens the {chapter_name}.tex file (by convention, this file exists)
(display-buffer-in-side-window
(find-file-noselect
(concat
(file-name-as-directory (eff-kw-chapter-path catg user-chapter))
(concat user-chapter ".tex")))
'((side . bottom) ; this is an associative list
(slot . 0)))))
(defun eff-compile-knowledge-with-catg (catg)
"Compile knowledge with CATG."
(let (user-chapter)
(setq user-chapter (eff-kw-read-chapter catg))
; run compile.py
(shell-command
(concat "cd " eff-knowledge-path "; "
(eff-pyenv-activate-command-string) "; "
"python compile.py -c " user-chapter))))
(defun eff-read-catg ()
"Read Category."
(let ((user-catg (completing-read
"Category: "
(list "technical" "nontechnical") nil 'confirm
"technical"
nil)))
user-catg))
(defun eff-add-knowledge-custom-catg ()
"Add technical knowledge note."
(interactive)
(let ((user-catg (eff-read-catg)))
(eff-add-knowledge-with-catg user-catg)))
(defun eff-compile-knowledge-custom-catg ()
"Add technical knowledge note."
(interactive)
(let ((user-catg (eff-read-catg)))
(eff-compile-knowledge-with-catg user-catg)))
(defalias 'eff-add-knowledge 'eff-add-knowledge-custom-catg)
(defalias 'eff-compile-knowledge 'eff-compile-knowledge-custom-catg)
(defun eff-commit-knowledge ()
"Commit by adding the file you're at now."
(interactive)
(let ((buffer-path)
(buffer-name)
(add-cmd)
(commit-cmd)
(commit-msg)
(output))
(setq buffer-path (buffer-file-name))
(setq buffer-name (file-name-nondirectory buffer-path))
(setq commit-msg (read-string (concat "Commit message [" buffer-name "]: ")))
(setq add-cmd (concat "git add " buffer-path))
(setq commit-cmd (concat "git commit -m \"" commit-msg "\""))
(let ((full-cmd (concat add-cmd "; " commit-cmd)))
(shell-command full-cmd)) ; this function returns shell command output in string
(with-output-to-temp-buffer "**Output**"
(print commit-cmd)
(print output))))
(defun eff-push-knowledge ()
"Push to remote."
(interactive)
(let ((remote (read-string "remote: " "origin"))
(branch (read-string "branch: " "master")))
(shell-command
(concat "git push " remote " " branch))))
;; Functions related to Developer or Life Notes
(defvar eff-notes-search-files-pattern nil)
(setq eff-notes-search-files-pattern nil)
(defun eff-search-build-grep-files-options (file-patterns)
"Return [--include <pattern> ...] where <pattern> comes from FILE-PATTERNS."
(let ((options-list ())) ; starts out as empty list
(setq file-patterns (split-string file-patterns))
(while file-patterns
(push (concat "--include " (car file-patterns) " ") options-list)
(setq file-patterns (cdr file-patterns)))
(apply #'concat options-list)))
(defun eff-search-pattern (pattern file-patterns root ignore-case-op)
"Performs search."
(print "HI")
(setq eff-notes-search-files-pattern file-patterns)
(let ((command (concat "grep -n -r " ignore-case-op " \"" pattern "\" " root " "
(eff-search-build-grep-files-options file-patterns))); regex pattern is not empty. Go ahead and search.
(search-result))
(eff-helper-message command)
(setq search-result (shell-command-to-string command))
(with-output-to-temp-buffer "*grep*"
(switch-to-buffer "*grep*") ;current buffer chagned to grep
(insert (concat command "\n"))
(insert search-result)
(grep-mode)
(visual-line-mode))))
(defun eff-search-read-inputs ()
"Read inputs for search."
(print "HELLO")
(let ((pattern (read-string "Regex Pattern: ")))
(if (eq (length pattern) 0)
(progn
(eff-helper-message "Regex pattern must not be empty.") ; regex pattern is empty. Do nothing.
nil)
(let ((file-patterns (read-string "File Pattern (separate by space): "
eff-notes-search-files-pattern))
(root (read-directory-name "Root: "
(concat eff-notes-repo-path "/Developer")))
(ignore-case-op
(if (string-prefix-p "y" (read-string "Ignore case (y)? " "y"))
"-i" "")))
(list pattern file-patterns root ignore-case-op)))))
(defun eff-search ()
"Search a substring under Notes/Developer or Notes/Life."
(interactive)
(let ((inputs (eff-search-read-inputs)))
(if (not (eq inputs nil))
(let ((pattern (nth 0 inputs))
(file-patterns (nth 1 inputs))
(root (nth 2 inputs))
(ignore-case-op (nth 3 inputs)))
(eff-search-pattern pattern file-patterns root ignore-case-op)))))
(defun eff-tex-make ()
"Builds latex document. Assumes there is a Makefile in the project."
(interactive)
(let ((proj-dir))
(setq proj-dir (read-string (concat "Latex project path (contains Makefile): ")
(file-name-directory buffer-file-name)))
(setq compile-mode (completing-read
"Mode: "
(list "pdf" "full" "quick")
nil t "full"))
(message (propertize "Compiling latex. Please wait..."))
(shell-command (concat "cd " proj-dir "; "
"make " compile-mode))))
(defun eff-helper-message (msg)
"Just message the MSG."
(message msg))
(defun eff-get (key a-list)
(cdr (assoc key a-list)))
(defun eff-start-terminal ()
"Start terminal in lisp"
(interactive)
(let ((root-path))
(setq root-path (read-directory-name "Root: "
(file-name-directory buffer-file-name)))
(shell-command (concat "cd " root-path "; gnome-terminal"))))
(provide 'my-functions)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment