add simple git mode
This commit is contained in:
192
.emacs.d/init.el
192
.emacs.d/init.el
@@ -38,9 +38,15 @@
|
||||
;; Search
|
||||
(require 'xah-find)
|
||||
|
||||
;; Git
|
||||
(require 'simple-git)
|
||||
|
||||
;; Debugging
|
||||
(require 'dape)
|
||||
|
||||
;; Emacs Debugging
|
||||
(require 'command-log-mode)
|
||||
|
||||
;;; ============================================================================
|
||||
;;; MODE ASSOCIATIONS
|
||||
;;; ============================================================================
|
||||
@@ -162,23 +168,23 @@ Start typing to search - LSP provides fuzzy matching."
|
||||
;; Kill debug session before quitting Emacs
|
||||
(add-hook 'kill-emacs-hook
|
||||
(lambda ()
|
||||
(ignore-errors (dape-quit))
|
||||
;; Also kill any lingering dlv processes
|
||||
(dolist (proc (process-list))
|
||||
(when (and (process-live-p proc)
|
||||
(string-match-p "\\(dape\\|dlv\\)" (process-name proc)))
|
||||
(ignore-errors
|
||||
(let ((pid (process-id proc)))
|
||||
(when pid (my-kill-process-tree pid)))
|
||||
(delete-process proc))))))
|
||||
(ignore-errors (dape-quit))))
|
||||
|
||||
(defun my-dape-start-or-continue ()
|
||||
"Start debugging or continue if already in a debug session.
|
||||
If stopped at a breakpoint, continue. Otherwise start a new debug session."
|
||||
If stopped at a breakpoint, continue. If running, do nothing.
|
||||
If no session active, start a new debug session."
|
||||
(interactive)
|
||||
(if-let ((conn (dape--live-connection 'stopped t)))
|
||||
(dape-continue conn)
|
||||
(call-interactively #'dape)))
|
||||
(cond
|
||||
;; Stopped at breakpoint - continue
|
||||
((dape--live-connection 'stopped t)
|
||||
(dape-continue (dape--live-connection 'stopped t)))
|
||||
;; Session active but running - do nothing
|
||||
((dape--live-connection 'parent t)
|
||||
(message "Debug session already running"))
|
||||
;; No session - start new one
|
||||
(t
|
||||
(call-interactively #'dape))))
|
||||
|
||||
;;; ============================================================================
|
||||
;;; FLYMAKE & DIAGNOSTICS
|
||||
@@ -344,7 +350,7 @@ If stopped at a breakpoint, continue. Otherwise start a new debug session."
|
||||
(setq compilation-scroll-output -1)
|
||||
(setq compilation-save-buffers-predicate 'ignore)
|
||||
|
||||
(defvar my-bottom-panel-buffers '("\\*compilation\\*" "\\*xref\\*" "\\*Flymake diagnostics.*\\*" "\\*grep\\*")
|
||||
(defvar my-bottom-panel-buffers '("\\*compilation\\*" "\\*xref\\*" "\\*Flymake diagnostics.*\\*" "\\*grep\\*" "\\*simple-git.*\\*")
|
||||
"List of buffer name patterns for bottom panel.")
|
||||
|
||||
(defun my-bottom-panel-buffer-p (buf)
|
||||
@@ -379,21 +385,62 @@ If stopped at a breakpoint, continue. Otherwise start a new debug session."
|
||||
'("\\*Flymake diagnostics.*\\*" (my-display-in-bottom-panel) (side . bottom) (slot . 1) (window-height . 0.25)))
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("\\*grep\\*" (my-display-in-bottom-panel) (side . bottom) (slot . 1) (window-height . 0.25)))
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("\\*simple-git.*\\*" (my-display-in-bottom-panel) (side . bottom) (slot . 1) (window-height . 0.25)))
|
||||
|
||||
(defun my-dape-panels-visible-p ()
|
||||
"Return non-nil if any dape panel is currently visible."
|
||||
(or (get-buffer-window "*dape-repl*")
|
||||
(cl-some #'get-buffer-window
|
||||
(seq-filter (lambda (buf)
|
||||
(string-prefix-p "*dape-info" (buffer-name buf)))
|
||||
(buffer-list)))))
|
||||
|
||||
(defun my-close-dape-panels ()
|
||||
"Close all dape panels."
|
||||
;; Close dape-repl
|
||||
(when-let ((win (get-buffer-window "*dape-repl*")))
|
||||
(delete-window win))
|
||||
;; Close dape-info buffers
|
||||
(dolist (buf (buffer-list))
|
||||
(when (string-prefix-p "*dape-info" (buffer-name buf))
|
||||
(when-let ((win (get-buffer-window buf)))
|
||||
(delete-window win)))))
|
||||
|
||||
(defun my-open-dape-panels ()
|
||||
"Open dape panels if debugging is active."
|
||||
(when (dape--live-connection 'parent t)
|
||||
(dape-info)
|
||||
(when (get-buffer "*dape-repl*")
|
||||
(dape-repl))))
|
||||
|
||||
(defun my-bottom-panel-toggle ()
|
||||
"Toggle the bottom panel. Close if visible, open if hidden."
|
||||
"Smart toggle for bottom panel and dape UI.
|
||||
If any panel is visible, close all. If none visible, open all."
|
||||
(interactive)
|
||||
(let ((panel-window (my-get-bottom-panel-window)))
|
||||
(if panel-window
|
||||
(delete-window panel-window)
|
||||
(let ((matching-buffers (seq-filter
|
||||
(lambda (buf)
|
||||
(seq-some (lambda (pat) (string-match-p pat (buffer-name buf)))
|
||||
my-bottom-panel-buffers))
|
||||
(buffer-list))))
|
||||
(if matching-buffers
|
||||
(my-display-in-bottom-panel (car matching-buffers) '((window-height . 0.25)))
|
||||
(message "No bottom panel buffers open."))))))
|
||||
(let ((bottom-visible (my-get-bottom-panel-window))
|
||||
(dape-visible (my-dape-panels-visible-p))
|
||||
(dape-active (dape--live-connection 'parent t)))
|
||||
(if (or bottom-visible dape-visible)
|
||||
;; Something is visible - close everything
|
||||
(progn
|
||||
(when bottom-visible
|
||||
(delete-window bottom-visible))
|
||||
(when dape-visible
|
||||
(my-close-dape-panels)))
|
||||
;; Nothing visible - open everything
|
||||
(progn
|
||||
;; Open dape panels if debugging
|
||||
(when dape-active
|
||||
(my-open-dape-panels))
|
||||
;; Open bottom panel if available
|
||||
(let ((matching-buffers (seq-filter
|
||||
(lambda (buf)
|
||||
(seq-some (lambda (pat) (string-match-p pat (buffer-name buf)))
|
||||
my-bottom-panel-buffers))
|
||||
(buffer-list))))
|
||||
(when matching-buffers
|
||||
(my-display-in-bottom-panel (car matching-buffers) '((window-height . 0.25)))))))))
|
||||
|
||||
;;; ============================================================================
|
||||
;;; BACKUP & AUTOSAVE SETTINGS
|
||||
@@ -415,26 +462,27 @@ If stopped at a breakpoint, continue. Otherwise start a new debug session."
|
||||
;;; PROCESS MANAGEMENT
|
||||
;;; ============================================================================
|
||||
|
||||
(defun my-kill-process-tree (pid)
|
||||
"Kill PID and all its descendant processes."
|
||||
(defun my-kill-process-tree (pid &optional kill-root)
|
||||
"Kill all descendant processes of PID. Also kill PID itself if KILL-ROOT is non-nil."
|
||||
(let ((children (split-string
|
||||
(shell-command-to-string
|
||||
(format "pgrep -P %d 2>/dev/null" pid))
|
||||
"\n" t)))
|
||||
(dolist (child children)
|
||||
(when (string-match "^[0-9]+$" child)
|
||||
(my-kill-process-tree (string-to-number child)))))
|
||||
(ignore-errors (call-process "kill" nil nil nil "-9" (number-to-string pid))))
|
||||
(my-kill-process-tree (string-to-number child) t)))) ; always kill descendants
|
||||
(when kill-root
|
||||
(ignore-errors (call-process "kill" nil nil nil "-9" (number-to-string pid)))))
|
||||
|
||||
;; Ensure all subprocesses are killed when Emacs exits
|
||||
(add-hook 'kill-emacs-hook
|
||||
(lambda ()
|
||||
;; Kill all child processes of Emacs (and their children)
|
||||
(my-kill-process-tree (emacs-pid))
|
||||
;; Also clean up via Emacs process list
|
||||
(dolist (proc (process-list))
|
||||
(when (process-live-p proc)
|
||||
(let ((pid (process-id proc)))
|
||||
(when pid
|
||||
(my-kill-process-tree pid)))
|
||||
(set-process-query-on-exit-flag proc t)
|
||||
(set-process-query-on-exit-flag proc nil)
|
||||
(ignore-errors (delete-process proc))))))
|
||||
|
||||
;; Kill terminal buffer when process exits
|
||||
@@ -468,6 +516,7 @@ If stopped at a breakpoint, continue. Otherwise start a new debug session."
|
||||
(global-set-key (kbd "C-n") (lambda () (interactive) (switch-to-buffer (generate-new-buffer "untitled"))))
|
||||
(global-set-key (kbd "C-o") 'find-file)
|
||||
(global-set-key (kbd "C-p") 'project-find-file)
|
||||
(global-set-key (kbd "C-S-p") 'execute-extended-command)
|
||||
(global-set-key (kbd "C-3") 'switch-to-buffer)
|
||||
(global-set-key (kbd "C-4") 'find-file)
|
||||
(global-set-key (kbd "C-q") 'save-buffers-kill-terminal)
|
||||
@@ -493,6 +542,7 @@ If stopped at a breakpoint, continue. Otherwise start a new debug session."
|
||||
|
||||
;; --- Clipboard & Kill Ring (CUA-style) ---
|
||||
(global-set-key (kbd "C-z") 'undo)
|
||||
(global-set-key (kbd "C-S-z") 'undo-redo)
|
||||
(global-set-key (kbd "C-v") 'clipboard-yank)
|
||||
(global-set-key (kbd "C-c") 'my-copy)
|
||||
(global-set-key (kbd "C-x") 'my-cut)
|
||||
@@ -557,10 +607,6 @@ If stopped at a breakpoint, continue. Otherwise start a new debug session."
|
||||
(global-set-key (kbd "<f6>") 'my-file-manager-command)
|
||||
(global-set-key (kbd "<C-f6>") 'my-terminal-emulator-command)
|
||||
|
||||
;; --- Project Management ---
|
||||
(global-set-key (kbd "<f7>") 'project-switch-project)
|
||||
(global-set-key (kbd "C-S-p") 'execute-extended-command)
|
||||
|
||||
;; --- Themes ---
|
||||
(global-set-key (kbd "<f3>") 'my-select-theme)
|
||||
|
||||
@@ -593,6 +639,10 @@ If stopped at a breakpoint, continue. Otherwise start a new debug session."
|
||||
(global-set-key (kbd "C-S-r") 'my-toggle-macro-recording)
|
||||
(global-set-key (kbd "C-M-r") 'my-call-macro)
|
||||
|
||||
;; --- Git ---
|
||||
(global-set-key (kbd "<f7>") 'simple-git-status)
|
||||
(global-set-key (kbd "C-<f7>") 'simple-git-file-history)
|
||||
|
||||
;; --- Misc ---
|
||||
(global-set-key (kbd "C-e") 'my-select-inside-parens)
|
||||
(global-set-key (kbd "C-y") 'my-copy-path-with-line)
|
||||
@@ -1150,31 +1200,38 @@ Does not copy to kill ring."
|
||||
;;; ============================================================================
|
||||
|
||||
(add-to-list 'custom-theme-load-path "~/.emacs.d/themes/")
|
||||
(defvar my-current-theme 'bedroom "Currently active theme.")
|
||||
(defcustom my-current-theme 'bedroom
|
||||
"Currently active theme. Saved automatically when changed."
|
||||
:type 'symbol
|
||||
:group 'my-settings)
|
||||
|
||||
(defun my-apply-builtin-theme (theme)
|
||||
"Apply a built-in color theme (not a real Emacs theme)."
|
||||
(pcase theme
|
||||
('default
|
||||
(set-foreground-color "black")
|
||||
(set-background-color "white"))
|
||||
('default-dark
|
||||
(set-foreground-color "white")
|
||||
(set-background-color "black"))
|
||||
('xah
|
||||
(set-foreground-color "black")
|
||||
(set-background-color "honeydew"))))
|
||||
|
||||
(defun my-select-theme ()
|
||||
"Select and load a theme from all available themes."
|
||||
"Select and load a theme from all available themes. Saves choice for next session."
|
||||
(interactive)
|
||||
(let* ((themes (append '("default" "default-dark" "xah") (mapcar #'symbol-name (custom-available-themes))))
|
||||
(choice (completing-read "Theme: " themes nil t)))
|
||||
(when my-current-theme
|
||||
(choice (completing-read "Theme: " themes nil t))
|
||||
(theme-sym (intern choice)))
|
||||
;; Disable current theme if it's a real theme
|
||||
(when (and my-current-theme
|
||||
(not (memq my-current-theme '(default default-dark xah))))
|
||||
(disable-theme my-current-theme))
|
||||
(cond
|
||||
((string= choice "default")
|
||||
(set-foreground-color "black")
|
||||
(set-background-color "white")
|
||||
(setq my-current-theme nil))
|
||||
((string= choice "default-dark")
|
||||
(set-foreground-color "white")
|
||||
(set-background-color "black")
|
||||
(setq my-current-theme nil))
|
||||
((string= choice "xah")
|
||||
(set-foreground-color "black")
|
||||
(set-background-color "honeydew")
|
||||
(setq my-current-theme nil))
|
||||
(t
|
||||
(setq my-current-theme (intern choice))
|
||||
(load-theme my-current-theme t)))))
|
||||
(if (memq theme-sym '(default default-dark xah))
|
||||
(my-apply-builtin-theme theme-sym)
|
||||
(load-theme theme-sym t))
|
||||
(customize-save-variable 'my-current-theme theme-sym)))
|
||||
|
||||
;;; ============================================================================
|
||||
;;; CUSTOM FUNCTIONS - Zoom
|
||||
@@ -1208,7 +1265,7 @@ Does not copy to kill ring."
|
||||
(when proc
|
||||
(let ((pid (process-id proc)))
|
||||
(when pid
|
||||
(my-kill-process-tree pid)))
|
||||
(my-kill-process-tree pid t)))
|
||||
(set-process-query-on-exit-flag proc nil)))
|
||||
(with-current-buffer buf
|
||||
(set-buffer-modified-p nil))
|
||||
@@ -1374,12 +1431,6 @@ Use in `isearch-mode-end-hook'."
|
||||
|
||||
;; (set-face-attribute 'default nil :font "Consolas-15")
|
||||
|
||||
;; Disable current theme before loading to prevent stacking on config reload
|
||||
(when my-current-theme
|
||||
(disable-theme my-current-theme))
|
||||
(setq my-current-theme 'bedroom)
|
||||
(load-theme 'bedroom t)
|
||||
|
||||
;;; ============================================================================
|
||||
;;; CUSTOM
|
||||
;;; ============================================================================
|
||||
@@ -1389,6 +1440,7 @@ Use in `isearch-mode-end-hook'."
|
||||
;; If you edit it by hand, you could mess it up, so be careful.
|
||||
;; Your init file should contain only one such instance.
|
||||
;; If there is more than one, they won't work right.
|
||||
'(my-current-theme 'valigo)
|
||||
'(safe-local-variable-directories '("/Users/mta/projects/cdrateline.com_2.0/")))
|
||||
(custom-set-faces
|
||||
;; custom-set-faces was added by Custom.
|
||||
@@ -1397,4 +1449,14 @@ Use in `isearch-mode-end-hook'."
|
||||
;; If there is more than one, they won't work right.
|
||||
)
|
||||
|
||||
;;; ============================================================================
|
||||
;;; LOAD THEME (must be after custom-set-variables)
|
||||
;;; ============================================================================
|
||||
|
||||
(mapc #'disable-theme custom-enabled-themes)
|
||||
(when my-current-theme
|
||||
(if (memq my-current-theme '(default default-dark xah))
|
||||
(my-apply-builtin-theme my-current-theme)
|
||||
(load-theme my-current-theme t)))
|
||||
|
||||
;;; init.el ends here
|
||||
|
||||
322
.emacs.d/lisp/command-log-mode.el
Normal file
322
.emacs.d/lisp/command-log-mode.el
Normal file
@@ -0,0 +1,322 @@
|
||||
;;; command-log-mode.el --- log keyboard commands to buffer
|
||||
|
||||
;; homepage: https://github.com/lewang/command-log-mode
|
||||
|
||||
;; Copyright (C) 2013 Nic Ferrier
|
||||
;; Copyright (C) 2012 Le Wang
|
||||
;; Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Michael Weber <michaelw@foldr.org>
|
||||
;; Keywords: help
|
||||
;; Initial-version: <2004-10-07 11:41:28 michaelw>
|
||||
;; Time-stamp: <2004-11-06 17:08:11 michaelw>
|
||||
|
||||
;; This file is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 2, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; This file is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
;; Boston, MA 02111-1307, USA.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This add-on can be used to demo Emacs to an audience. When
|
||||
;; activated, keystrokes get logged into a designated buffer, along
|
||||
;; with the command bound to them.
|
||||
|
||||
;; To enable, use e.g.:
|
||||
;;
|
||||
;; (require 'command-log-mode)
|
||||
;; (add-hook 'LaTeX-mode-hook 'command-log-mode)
|
||||
;;
|
||||
;; To see the log buffer, call M-x clm/open-command-log-buffer.
|
||||
|
||||
;; The key strokes in the log are decorated with ISO9601 timestamps on
|
||||
;; the property `:time' so if you want to convert the log for
|
||||
;; screencasting purposes you could use the time stamp as a key into
|
||||
;; the video beginning.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(eval-when-compile (require 'cl))
|
||||
|
||||
(defvar clm/log-text t
|
||||
"A non-nil setting means text will be saved to the command log.")
|
||||
|
||||
(defvar clm/log-repeat nil
|
||||
"A nil setting means repetitions of the same command are merged into the single log line.")
|
||||
|
||||
(defvar clm/recent-history-string ""
|
||||
"This string will hold recently typed text.")
|
||||
|
||||
(defun clm/recent-history ()
|
||||
(setq clm/recent-history-string
|
||||
(concat clm/recent-history-string
|
||||
(buffer-substring-no-properties (- (point) 1) (point)))))
|
||||
|
||||
(add-hook 'post-self-insert-hook 'clm/recent-history)
|
||||
|
||||
(defun clm/zap-recent-history ()
|
||||
(unless (or (member this-original-command
|
||||
clm/log-command-exceptions*)
|
||||
(eq this-original-command #'self-insert-command))
|
||||
(setq clm/recent-history-string "")))
|
||||
|
||||
(add-hook 'post-command-hook 'clm/zap-recent-history)
|
||||
|
||||
(defvar clm/time-string "%Y-%m-%dT%H:%M:%S"
|
||||
"The string sent to `format-time-string' when command time is logged.")
|
||||
|
||||
(defvar clm/logging-dir "~/log/"
|
||||
"Directory in which to store files containing logged commands.")
|
||||
|
||||
(defvar clm/log-command-exceptions*
|
||||
'(nil self-insert-command backward-char forward-char
|
||||
delete-char delete-backward-char backward-delete-char
|
||||
backward-delete-char-untabify
|
||||
universal-argument universal-argument-other-key
|
||||
universal-argument-minus universal-argument-more
|
||||
beginning-of-line end-of-line recenter
|
||||
move-end-of-line move-beginning-of-line
|
||||
handle-switch-frame
|
||||
newline previous-line next-line)
|
||||
"A list commands which should not be logged, despite logging being enabled.
|
||||
Frequently used non-interesting commands (like cursor movements) should be put here.")
|
||||
|
||||
(defvar clm/command-log-buffer nil
|
||||
"Reference of the currenly used buffer to display logged commands.")
|
||||
(defvar clm/command-repetitions 0
|
||||
"Count of how often the last keyboard commands has been repeated.")
|
||||
(defvar clm/last-keyboard-command nil
|
||||
"Last logged keyboard command.")
|
||||
|
||||
|
||||
(defvar clm/log-command-indentation 11
|
||||
"*Indentation of commands in command log buffer.")
|
||||
|
||||
(defgroup command-log nil
|
||||
"Customization for the command log.")
|
||||
|
||||
(defcustom command-log-mode-auto-show nil
|
||||
"Show the command-log window or frame automatically."
|
||||
:group 'command-log
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom command-log-mode-window-size 40
|
||||
"The size of the command-log window."
|
||||
:group 'command-log
|
||||
:type 'integer)
|
||||
|
||||
(defcustom command-log-mode-window-font-size 2
|
||||
"The font-size of the command-log window."
|
||||
:group 'command-log
|
||||
:type 'integer)
|
||||
|
||||
(defcustom command-log-mode-key-binding-open-log "C-c o"
|
||||
"The key binding used to toggle the log window."
|
||||
:group 'command-log
|
||||
:type '(radio
|
||||
(const :tag "No key" nil)
|
||||
(key-sequence "C-c o"))) ;; this is not right though it works for kbd
|
||||
|
||||
(defcustom command-log-mode-open-log-turns-on-mode nil
|
||||
"Does opening the command log turn on the mode?"
|
||||
:group 'command-log
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom command-log-mode-is-global nil
|
||||
"Does turning on command-log-mode happen globally?"
|
||||
:group 'command-log
|
||||
:type 'boolean)
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode command-log-mode
|
||||
"Toggle keyboard command logging."
|
||||
:init-value nil
|
||||
:lighter " command-log"
|
||||
:keymap nil
|
||||
(if command-log-mode
|
||||
(when (and
|
||||
command-log-mode-auto-show
|
||||
(not (get-buffer-window clm/command-log-buffer)))
|
||||
(clm/open-command-log-buffer))
|
||||
;; We can close the window though
|
||||
(clm/close-command-log-buffer)))
|
||||
|
||||
(define-global-minor-mode global-command-log-mode command-log-mode
|
||||
command-log-mode)
|
||||
|
||||
(defun clm/buffer-log-command-p (cmd &optional buffer)
|
||||
"Determines whether keyboard command CMD should be logged.
|
||||
If non-nil, BUFFER specifies the buffer used to determine whether CMD should be logged.
|
||||
If BUFFER is nil, the current buffer is assumed."
|
||||
(let ((val (if buffer
|
||||
(buffer-local-value command-log-mode buffer)
|
||||
command-log-mode)))
|
||||
(and (not (null val))
|
||||
(null (member cmd clm/log-command-exceptions*)))))
|
||||
|
||||
(defmacro clm/save-command-environment (&rest body)
|
||||
(declare (indent 0))
|
||||
`(let ((deactivate-mark nil) ; do not deactivate mark in transient
|
||||
; mark mode
|
||||
;; do not let random commands scribble over
|
||||
;; {THIS,LAST}-COMMAND
|
||||
(this-command this-command)
|
||||
(last-command last-command))
|
||||
,@body))
|
||||
|
||||
(defun clm/open-command-log-buffer (&optional arg)
|
||||
"Opens (and creates, if non-existant) a buffer used for logging keyboard commands.
|
||||
If ARG is Non-nil, the existing command log buffer is cleared."
|
||||
(interactive "P")
|
||||
(with-current-buffer
|
||||
(setq clm/command-log-buffer
|
||||
(get-buffer-create " *command-log*"))
|
||||
(text-scale-set 1))
|
||||
(when arg
|
||||
(with-current-buffer clm/command-log-buffer
|
||||
(erase-buffer)))
|
||||
(let ((new-win (split-window-horizontally
|
||||
(- 0 command-log-mode-window-size))))
|
||||
(set-window-buffer new-win clm/command-log-buffer)
|
||||
(set-window-dedicated-p new-win t)))
|
||||
|
||||
(defun clm/close-command-log-buffer ()
|
||||
"Close the command log window."
|
||||
(interactive)
|
||||
(with-current-buffer
|
||||
(setq clm/command-log-buffer
|
||||
(get-buffer-create " *command-log*"))
|
||||
(let ((win (get-buffer-window (current-buffer))))
|
||||
(when (windowp win)
|
||||
(delete-window win)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun clm/toggle-command-log-buffer (&optional arg)
|
||||
"Toggle the command log showing or not."
|
||||
(interactive "P")
|
||||
(when (and command-log-mode-open-log-turns-on-mode
|
||||
(not command-log-mode))
|
||||
(if command-log-mode-is-global
|
||||
(global-command-log-mode)
|
||||
(command-log-mode)))
|
||||
(with-current-buffer
|
||||
(setq clm/command-log-buffer
|
||||
(get-buffer-create " *command-log*"))
|
||||
(let ((win (get-buffer-window (current-buffer))))
|
||||
(if (windowp win)
|
||||
(clm/close-command-log-buffer)
|
||||
;; Else open the window
|
||||
(clm/open-command-log-buffer arg)))))
|
||||
|
||||
(defun clm/scroll-buffer-window (buffer &optional move-fn)
|
||||
"Updates `point' of windows containing BUFFER according to MOVE-FN.
|
||||
If non-nil, MOVE-FN is called on every window which displays BUFFER.
|
||||
If nil, MOVE-FN defaults to scrolling to the bottom, making the last line visible.
|
||||
|
||||
Scrolling up can be accomplished with:
|
||||
\(clm/scroll-buffer-window buf (lambda () (goto-char (point-min))))
|
||||
"
|
||||
(let ((selected (selected-window))
|
||||
(point-mover (or move-fn
|
||||
(function (lambda () (goto-char (point-max)))))))
|
||||
(walk-windows (function (lambda (window)
|
||||
(when (eq (window-buffer window) buffer)
|
||||
(select-window window)
|
||||
(funcall point-mover)
|
||||
(select-window selected))))
|
||||
nil t)))
|
||||
|
||||
(defmacro clm/with-command-log-buffer (&rest body)
|
||||
(declare (indent 0))
|
||||
`(when (and (not (null clm/command-log-buffer))
|
||||
(buffer-name clm/command-log-buffer))
|
||||
(with-current-buffer clm/command-log-buffer
|
||||
,@body)))
|
||||
|
||||
(defun clm/log-command (&optional cmd)
|
||||
"Hook into `pre-command-hook' to intercept command activation."
|
||||
(clm/save-command-environment
|
||||
(setq cmd (or cmd this-command))
|
||||
(when (clm/buffer-log-command-p cmd)
|
||||
(clm/with-command-log-buffer
|
||||
(let ((current (current-buffer)))
|
||||
(goto-char (point-max))
|
||||
(cond ((and (not clm/log-repeat) (eq cmd clm/last-keyboard-command))
|
||||
(incf clm/command-repetitions)
|
||||
(save-match-data
|
||||
(when (and (> clm/command-repetitions 1)
|
||||
(search-backward "[" (line-beginning-position -1) t))
|
||||
(delete-region (point) (line-end-position))))
|
||||
(backward-char) ; skip over either ?\newline or ?\space before ?\[
|
||||
(insert " [")
|
||||
(princ (1+ clm/command-repetitions) current)
|
||||
(insert " times]"))
|
||||
(t ;; (message "last cmd: %s cur: %s" last-command cmd)
|
||||
;; showing accumulated text with interleaved key presses isn't very useful
|
||||
(when (and clm/log-text (not clm/log-repeat))
|
||||
(if (eq clm/last-keyboard-command 'self-insert-command)
|
||||
(insert "[text: " clm/recent-history-string "]\n")))
|
||||
(setq clm/command-repetitions 0)
|
||||
(insert
|
||||
(propertize
|
||||
(key-description (this-command-keys))
|
||||
:time (format-time-string clm/time-string (current-time))))
|
||||
(when (>= (current-column) clm/log-command-indentation)
|
||||
(newline))
|
||||
(move-to-column clm/log-command-indentation t)
|
||||
(princ (if (byte-code-function-p cmd) "<bytecode>" cmd) current)
|
||||
(newline)
|
||||
(setq clm/last-keyboard-command cmd)))
|
||||
(clm/scroll-buffer-window current))))))
|
||||
|
||||
(defun clm/command-log-clear ()
|
||||
"Clear the command log buffer."
|
||||
(interactive)
|
||||
(with-current-buffer clm/command-log-buffer
|
||||
(erase-buffer)))
|
||||
|
||||
(defun clm/save-log-line (start end)
|
||||
"Helper function for `clm/save-command-log' to export text properties."
|
||||
(save-excursion
|
||||
(goto-char start)
|
||||
(let ((time (get-text-property (point) :time)))
|
||||
(if time
|
||||
(list (cons start (if time
|
||||
(concat "[" (get-text-property (point) :time) "] ")
|
||||
"")))))))
|
||||
|
||||
(defun clm/save-command-log ()
|
||||
"Save commands to today's log.
|
||||
Clears the command log buffer after saving."
|
||||
(interactive)
|
||||
(save-window-excursion
|
||||
(set-buffer (get-buffer " *command-log*"))
|
||||
(goto-char (point-min))
|
||||
(let ((now (format-time-string "%Y-%m-%d"))
|
||||
(write-region-annotate-functions '(clm/save-log-line)))
|
||||
(while (and (re-search-forward "^.*" nil t)
|
||||
(not (eobp)))
|
||||
(append-to-file (line-beginning-position) (1+ (line-end-position)) (concat clm/logging-dir now))))
|
||||
(clm/command-log-clear)))
|
||||
|
||||
(add-hook 'pre-command-hook 'clm/log-command)
|
||||
|
||||
(eval-after-load 'command-log-mode
|
||||
'(when command-log-mode-key-binding-open-log
|
||||
(global-set-key
|
||||
(kbd command-log-mode-key-binding-open-log)
|
||||
'clm/toggle-command-log-buffer)))
|
||||
|
||||
(provide 'command-log-mode)
|
||||
|
||||
;;; command-log-mode.el ends here
|
||||
1151
.emacs.d/lisp/simple-git.el
Normal file
1151
.emacs.d/lisp/simple-git.el
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user