init
This commit is contained in:
BIN
.emacs.d/.DS_Store
vendored
Normal file
BIN
.emacs.d/.DS_Store
vendored
Normal file
Binary file not shown.
13
.emacs.d/custom.el
Executable file
13
.emacs.d/custom.el
Executable file
@@ -0,0 +1,13 @@
|
||||
(custom-set-variables
|
||||
;; custom-set-variables was added by Custom.
|
||||
;; 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.
|
||||
'(custom-safe-themes
|
||||
'("5e38acfff91084e4c8174e272d2f8b84808884b4f49c62145b48810ec1766b5e" "eb085d94b1f7bfa54c7003bf7edb40eab1133d90cfebcf1d11be5959635a526f" default)))
|
||||
(custom-set-faces
|
||||
;; custom-set-faces was added by Custom.
|
||||
;; 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.
|
||||
)
|
||||
251
.emacs.d/init.el
Executable file
251
.emacs.d/init.el
Executable file
@@ -0,0 +1,251 @@
|
||||
;; Max's init.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; General Configuration
|
||||
|
||||
;; set load paths for lisp evaluation
|
||||
(add-to-list 'load-path "~/.emacs.d/lisp/")
|
||||
|
||||
(let ((default-directory "~/.emacs.d/lisp/"))
|
||||
(normal-top-level-add-subdirs-to-load-path))
|
||||
|
||||
(setq indent-tabs-mode t)
|
||||
(stupid-indent-mode)
|
||||
(setq-local stupid-indent-level 4)
|
||||
))
|
||||
|
||||
;; general settings
|
||||
(setq-default inhibit-startup-screen t)
|
||||
(show-paren-mode 1)
|
||||
(delete-selection-mode 1)
|
||||
(setq cua-auto-tabify-rectangles nil) ;; Don't tabify after rectangle commands
|
||||
(transient-mark-mode 1) ;; No region when it is not highlighted
|
||||
(setq cua-keep-region-after-copy nil) ;; don't reselect after copy
|
||||
(menu-bar-mode -1)
|
||||
(scroll-bar-mode -1)
|
||||
(tool-bar-mode -1)
|
||||
(global-auto-revert-mode t)
|
||||
(electric-pair-mode -1)
|
||||
(setq ns-pop-up-frames nil)
|
||||
(setq initial-major-mode 'text-mode)
|
||||
(setq initial-scratch-message "Just give him some food, water, and a funny hat." )
|
||||
(setq ediff-split-window-function 'split-window-horizontally)
|
||||
(setq-default truncate-lines 1)
|
||||
(setq column-number-mode t)
|
||||
(setq dired-dnd-protocol-alist nil)
|
||||
(global-so-long-mode 1)
|
||||
(column-number-mode 1)
|
||||
(blink-cursor-mode 0)
|
||||
(setq use-dialog-box nil)
|
||||
(electric-indent-mode 0)
|
||||
(tooltip-mode -1)
|
||||
(setq-default select-enable-clipboard nil)
|
||||
(setq-default x-select-enable-clipboard nil)
|
||||
(setq-default backward-delete-char-untabify-method nil)
|
||||
(setq ring-bell-function 'ignore)
|
||||
(setq custom-file "~/.emacs.d/custom.el") ;; place custom in a separate file
|
||||
(setq-default require-final-newline t)
|
||||
(cua-mode t)
|
||||
|
||||
;; backup and autosave settings
|
||||
(setq backup-by-copying t ; don't clobber symlinks
|
||||
backup-directory-alist '(("." . "~/.emacs.d/saves/")) ; don't litter my fs tree
|
||||
delete-old-versions t
|
||||
kept-new-versions 6
|
||||
kept-old-versions 2
|
||||
version-control t) ; use versioned backups
|
||||
(setq auto-save-file-name-transforms
|
||||
`((".*" "~/.emacs.d/saves/" t)))
|
||||
(setq create-lockfiles nil)
|
||||
|
||||
;; Keybindings / Keybinds
|
||||
;; global
|
||||
(global-set-key (kbd "S-<down-mouse-1>") #'my-mouse-start-rectangle)
|
||||
(global-set-key (kbd "<f5>") 'revert-buffer-quick)
|
||||
(global-set-key (kbd "<f6>") 'my-file-manager-command)
|
||||
(global-set-key (kbd "<C-f6>") 'my-terminal-emulator-command)
|
||||
(global-set-key [f8] 'goto-line)
|
||||
(global-set-key (kbd "C-\\") 'my-transpose-windows)
|
||||
(global-unset-key (kbd "C-x C-SPC"))
|
||||
(global-set-key (kbd "C-x C-SPC") 'rectangle-mark-mode)
|
||||
(global-set-key [C-return] 'save-buffer)
|
||||
(global-set-key [?\C-z] 'undo)
|
||||
(global-set-key (kbd "C-*") 'search-current-word)
|
||||
(global-set-key (kbd "C-;") 'comment-line)
|
||||
(global-set-key (kbd "M-<f4>") 'save-buffers-kill-terminal) ;; windows thing
|
||||
(global-set-key (kbd "C-y") 'clipboard-yank) ;; fix killring messing with system clipboard
|
||||
(global-set-key (kbd "C-w") 'clipboard-kill-region)
|
||||
(global-set-key (kbd "M-w") 'clipboard-kill-ring-save)
|
||||
(global-set-key (kbd "M-j") 'my-duplicate-line)
|
||||
(global-set-key (kbd "<f9>") 'bookmark-jump)
|
||||
(global-set-key (kbd "<f10>") 'bookmark-set)
|
||||
(global-set-key (kbd "<f11>") 'bookmark-delete)
|
||||
|
||||
;; custom bind minor mode
|
||||
;; this allows binding keys that override all other modes
|
||||
(defvar my-keys-minor-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map (kbd "M-p") 'backward-paragraph)
|
||||
(define-key map (kbd "M-n") 'forward-paragraph)
|
||||
(define-key map (kbd "C-o") 'next-multiframe-window)
|
||||
(define-key map [?\C-0] 'delete-window)
|
||||
(define-key map [?\C-1] 'delete-other-windows)
|
||||
(define-key map [?\C-2] 'split-window-vertically)
|
||||
(define-key map [?\C-3] 'split-window-horizontally)
|
||||
(define-key map [?\C-4] 'find-file-at-point)
|
||||
(define-key map [?\C-5] 'switch-to-buffer)
|
||||
(define-key map (kbd "C-j") 'dabbrev-expand)
|
||||
map)
|
||||
"my-keys-minor-mode keymap.")
|
||||
|
||||
(define-minor-mode my-keys-minor-mode
|
||||
"A minor mode so that my key settings override annoying major modes."
|
||||
:init-value t
|
||||
:lighter "")
|
||||
|
||||
;; don't enable override keymap in minibuf
|
||||
(defun my-minibuffer-setup-hook ()
|
||||
(my-keys-minor-mode 0))
|
||||
(add-hook 'minibuffer-setup-hook 'my-minibuffer-setup-hook)
|
||||
|
||||
(my-keys-minor-mode 1)
|
||||
|
||||
;; Custom Functions
|
||||
|
||||
;; test function
|
||||
(defun my-test ()
|
||||
(interactive)
|
||||
(message "Hello world!"))
|
||||
|
||||
;; duplicate line (cleanly)
|
||||
;; https://stackoverflow.com/questions/88399/how-do-i-duplicate-a-whole-line-in-emacs
|
||||
(defun my-duplicate-line (arg)
|
||||
"Duplicate current line, leaving point in lower line."
|
||||
(interactive "*p")
|
||||
(setq buffer-undo-list (cons (point) buffer-undo-list))
|
||||
(let ((bol (save-excursion (beginning-of-line) (point)))
|
||||
eol)
|
||||
(save-excursion
|
||||
(end-of-line)
|
||||
(setq eol (point))
|
||||
(let ((line (buffer-substring bol eol))
|
||||
(buffer-undo-list t)
|
||||
(count arg))
|
||||
(while (> count 0)
|
||||
(newline)
|
||||
(insert line)
|
||||
(setq count (1- count)))
|
||||
)
|
||||
(setq buffer-undo-list (cons (cons eol (point)) buffer-undo-list)))
|
||||
)
|
||||
(next-line arg))
|
||||
|
||||
;; select rectangle with shift+mouse
|
||||
(defun my-mouse-start-rectangle (start-event)
|
||||
(interactive "e")
|
||||
(deactivate-mark)
|
||||
(mouse-set-point start-event)
|
||||
(rectangle-mark-mode +1)
|
||||
(let ((drag-event))
|
||||
(track-mouse
|
||||
(while (progn
|
||||
(setq drag-event (read-event))
|
||||
(mouse-movement-p drag-event))
|
||||
(mouse-set-point drag-event)))))
|
||||
|
||||
;; open file manager
|
||||
(defun my-file-manager-command ()
|
||||
(interactive)
|
||||
(cond ((eq system-type 'windows-nt)
|
||||
(shell-command "explorer.exe ."))
|
||||
((eq system-type 'gnu/linux)
|
||||
(shell-command "setsid -f nautilus . >/dev/null 2>&1"))))
|
||||
|
||||
;; open terminal or cmd prompt
|
||||
(defun my-terminal-emulator-command ()
|
||||
(interactive)
|
||||
(cond ((eq system-type 'windows-nt)
|
||||
(let ((proc (start-process "cmd" nil "cmd.exe" "/C" "start" "cmd.exe")))
|
||||
(set-process-query-on-exit-flag proc nil)))
|
||||
((eq system-type 'gnu/linux)
|
||||
(shell-command "setsid -f gnome-terminal . >/dev/null 2>&1"))))
|
||||
|
||||
;; transpose (move) windows
|
||||
(defun my-transpose-windows (arg)
|
||||
"Transpose the buffers shown in two windows."
|
||||
(interactive "p")
|
||||
(let ((selector (if (>= arg 0) 'next-window 'previous-window)))
|
||||
(while (/= arg 0)
|
||||
(let ((this-win (window-buffer))
|
||||
(next-win (window-buffer (funcall selector))))
|
||||
(set-window-buffer (selected-window) next-win)
|
||||
(set-window-buffer (funcall selector) this-win)
|
||||
(select-window (funcall selector)))
|
||||
(setq arg (if (plusp arg) (1- arg) (1+ arg))))))
|
||||
|
||||
;; search current word
|
||||
(defun search-current-word ()
|
||||
(interactive)
|
||||
(let ($p1 $p2)
|
||||
(if (region-active-p)
|
||||
(setq $p1 (region-beginning) $p2 (region-end))
|
||||
(save-excursion
|
||||
|
||||
(skip-chars-backward "-_A-Za-z0-9")
|
||||
(setq $p1 (point))
|
||||
(right-char)
|
||||
(skip-chars-forward "-_A-Za-z0-9")
|
||||
(setq $p2 (point))))
|
||||
(setq mark-active nil)
|
||||
(when (< $p1 (point))
|
||||
(goto-char $p1))
|
||||
(isearch-mode t)
|
||||
(isearch-yank-string (buffer-substring-no-properties $p1 $p2))))
|
||||
|
||||
;; Tweaks / Fixes
|
||||
;; Emacs sucks by default, here are some fixes.
|
||||
|
||||
;; fix isearch
|
||||
(defadvice isearch-search (after isearch-no-fail activate)
|
||||
(unless isearch-success
|
||||
(ad-disable-advice 'isearch-search 'after 'isearch-no-fail)
|
||||
(ad-activate 'isearch-search)
|
||||
(isearch-repeat (if isearch-forward 'forward))
|
||||
(ad-enable-advice 'isearch-search 'after 'isearch-no-fail)
|
||||
(ad-activate 'isearch-search)))
|
||||
|
||||
(add-hook 'isearch-mode-end-hook
|
||||
#'endless/goto-match-beginning)
|
||||
|
||||
(defun endless/goto-match-beginning ()
|
||||
"Go to the start of current isearch match.
|
||||
Use in `isearch-mode-end-hook'."
|
||||
(when (and isearch-forward
|
||||
(number-or-marker-p isearch-other-end)
|
||||
(not mark-active)
|
||||
(not isearch-mode-end-hook-quit))
|
||||
(goto-char isearch-other-end)))
|
||||
|
||||
;; appearance
|
||||
;; (set-face-attribute 'default nil :font "Consolas-15")
|
||||
|
||||
;; the name of my emacs color scheme
|
||||
(custom-set-faces
|
||||
'(default ((t (:foreground "#d3b58d" :background "#181E2C"))))
|
||||
'(custom-group-tag-face ((t (:underline t :foreground "lightblue"))) t)
|
||||
'(custom-variable-tag-face ((t (:underline t :foreground "lightblue"))) t)
|
||||
'(font-lock-builtin-face ((t nil)))
|
||||
'(font-lock-comment-face ((t (:foreground "#bf9319"))))
|
||||
'(font-lock-function-name-face ((((class color) (background dark)) (:foreground "white"))))
|
||||
'(font-lock-keyword-face ((t (:foreground "white" ))))
|
||||
'(font-lock-string-face ((t (:foreground "#8fcddb"))))
|
||||
'(font-lock-variable-name-face ((((class color) (background dark)) (:foreground "#c8d4ec"))))
|
||||
'(font-lock-warning-face ((t (:foreground "#504038"))))
|
||||
'(highlight ((t (:foreground "navyblue" :background "darkseagreen2"))))
|
||||
'(mode-line ((t (:inverse-video t))))
|
||||
'(region ((t (:background "blue"))))
|
||||
'(widget-field-face ((t (:foreground "white"))) t)
|
||||
'(widget-single-line-field-face ((t (:background "darkgray"))) t))
|
||||
|
||||
(set-background-color "#181E2C")
|
||||
(global-font-lock-mode 1)
|
||||
(set-cursor-color "lightgreen")
|
||||
3056
.emacs.d/lisp/go-mode.el
Executable file
3056
.emacs.d/lisp/go-mode.el
Executable file
File diff suppressed because it is too large
Load Diff
233
.emacs.d/lisp/jai-mode.el
Executable file
233
.emacs.d/lisp/jai-mode.el
Executable file
@@ -0,0 +1,233 @@
|
||||
;;; jai-mode.el --- Major mode for JAI -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2015-2023 Kristoffer Grönlund
|
||||
|
||||
;; Author: Kristoffer Grönlund <k@ziran.se>
|
||||
;; Maintainer: Kristoffer Grönlund <k@ziran.se>
|
||||
;; URL: https://github.com/krig/jai-mode
|
||||
;; Version: 0.0.1
|
||||
;; Package-Requires: ((emacs "26.1"))
|
||||
;; Keywords: languages
|
||||
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;; This program 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 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; Major mdoe for JAI
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'rx)
|
||||
(require 'js)
|
||||
(require 'compile)
|
||||
|
||||
(defconst jai-mode-syntax-table
|
||||
(let ((table (make-syntax-table)))
|
||||
(modify-syntax-entry ?\" "\"" table)
|
||||
(modify-syntax-entry ?\\ "\\" table)
|
||||
|
||||
;; additional symbols
|
||||
(modify-syntax-entry ?_ "w" table)
|
||||
|
||||
(modify-syntax-entry ?' "." table)
|
||||
(modify-syntax-entry ?: "." table)
|
||||
(modify-syntax-entry ?+ "." table)
|
||||
(modify-syntax-entry ?- "." table)
|
||||
(modify-syntax-entry ?% "." table)
|
||||
(modify-syntax-entry ?& "." table)
|
||||
(modify-syntax-entry ?| "." table)
|
||||
(modify-syntax-entry ?^ "." table)
|
||||
(modify-syntax-entry ?! "." table)
|
||||
(modify-syntax-entry ?= "." table)
|
||||
(modify-syntax-entry ?< "." table)
|
||||
(modify-syntax-entry ?> "." table)
|
||||
(modify-syntax-entry ?? "." table)
|
||||
|
||||
;; Modify some syntax entries to allow nested block comments
|
||||
(modify-syntax-entry ?/ ". 124b" table)
|
||||
(modify-syntax-entry ?* ". 23n" table)
|
||||
(modify-syntax-entry ?\n "> b" table)
|
||||
(modify-syntax-entry ?\^m "> b" table)
|
||||
|
||||
table))
|
||||
|
||||
(defconst jai-builtins
|
||||
'("it" "it_index"))
|
||||
|
||||
(defconst jai-keywords
|
||||
'("if" "ifx" "else" "then" "while" "for" "switch" "case" "struct" "enum"
|
||||
"return" "remove" "continue" "break" "defer" "inline" "no_inline"
|
||||
"using" "code_of" "initializer_of" "size_of" "type_of" "cast" "type_info"
|
||||
"null" "true" "false" "xx" "context" "operator" "push_context" "is_constant"
|
||||
"enum_flags" "union" "interface"))
|
||||
|
||||
(defconst jai-typenames
|
||||
'("int" "u64" "u32" "u16" "u8"
|
||||
"s64" "s32" "s16" "s8" "float"
|
||||
"float32" "float64" "string"
|
||||
"bool"))
|
||||
|
||||
(defun jai-wrap-word-rx (s)
|
||||
(concat "\\<" s "\\>"))
|
||||
|
||||
(defun jai-keywords-rx (keywords)
|
||||
"build keyword regexp"
|
||||
(jai-wrap-word-rx (regexp-opt keywords t)))
|
||||
|
||||
(defconst jai-hat-type-rx (rx (group (and "^" (1+ word)))))
|
||||
(defconst jai-dollar-type-rx (rx (group "$" (or (1+ word) (opt "$")))))
|
||||
(defconst jai-number-rx
|
||||
(rx (and
|
||||
symbol-start
|
||||
(or (and (+ digit) (opt (and (any "eE") (opt (any "-+")) (+ digit))))
|
||||
(and "0" (any "xX") (+ hex-digit)))
|
||||
(opt (and (any "_" "A-Z" "a-z") (* (any "_" "A-Z" "a-z" "0-9"))))
|
||||
symbol-end)))
|
||||
|
||||
(defconst jai-font-lock-defaults
|
||||
`(;; Keywords
|
||||
(,(jai-keywords-rx jai-keywords) 1 font-lock-keyword-face)
|
||||
|
||||
;; single quote characters
|
||||
("\\('[[:word:]]\\)\\>" 1 font-lock-constant-face)
|
||||
|
||||
;; Variables
|
||||
(,(jai-keywords-rx jai-builtins) 1 font-lock-variable-name-face)
|
||||
|
||||
;; Hash directives
|
||||
("#\\w+" . font-lock-preprocessor-face)
|
||||
|
||||
;; At notes
|
||||
("@\\w+" . font-lock-preprocessor-face)
|
||||
|
||||
;; Strings
|
||||
("\\\".*\\\"" . font-lock-string-face)
|
||||
|
||||
;; Numbers
|
||||
(,(jai-wrap-word-rx jai-number-rx) . font-lock-constant-face)
|
||||
|
||||
;; Types
|
||||
(,(jai-keywords-rx jai-typenames) 1 font-lock-type-face)
|
||||
(,jai-hat-type-rx 1 font-lock-type-face)
|
||||
(,jai-dollar-type-rx 1 font-lock-type-face)
|
||||
|
||||
("---" . font-lock-constant-face)))
|
||||
|
||||
;; add setq-local for older emacs versions
|
||||
(unless (fboundp 'setq-local)
|
||||
(defmacro setq-local (var val)
|
||||
`(set (make-local-variable ',var) ,val)))
|
||||
|
||||
(defconst jai--defun-rx "\(.*\).*\{")
|
||||
|
||||
(defmacro jai-paren-level ()
|
||||
`(car (syntax-ppss)))
|
||||
|
||||
(defun jai-line-is-defun ()
|
||||
"return t if current line begins a procedure"
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(beginning-of-line)
|
||||
(let (found)
|
||||
(while (and (not (eolp)) (not found))
|
||||
(if (looking-at jai--defun-rx)
|
||||
(setq found t)
|
||||
(forward-char 1)))
|
||||
found)))
|
||||
|
||||
(defun jai-beginning-of-defun ()
|
||||
"Go to line on which current function starts."
|
||||
(interactive)
|
||||
(let ((orig-level (jai-paren-level)))
|
||||
(while (and
|
||||
(not (jai-line-is-defun))
|
||||
(not (bobp))
|
||||
(> orig-level 0))
|
||||
(setq orig-level (jai-paren-level))
|
||||
(while (>= (jai-paren-level) orig-level)
|
||||
(skip-chars-backward "^{")
|
||||
(backward-char))))
|
||||
(when (jai-line-is-defun)
|
||||
(beginning-of-line)))
|
||||
|
||||
(defun jai-end-of-defun ()
|
||||
"Go to line on which current function ends."
|
||||
(interactive)
|
||||
(let ((orig-level (jai-paren-level)))
|
||||
(when (> orig-level 0)
|
||||
(jai-beginning-of-defun)
|
||||
(end-of-line)
|
||||
(setq orig-level (jai-paren-level))
|
||||
(skip-chars-forward "^}")
|
||||
(while (>= (jai-paren-level) orig-level)
|
||||
(skip-chars-forward "^}")
|
||||
(forward-char)))))
|
||||
|
||||
(defalias 'jai-parent-mode
|
||||
(if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode))
|
||||
|
||||
;; imenu hookup
|
||||
(add-hook 'jai-mode-hook
|
||||
(lambda ()
|
||||
(setq imenu-generic-expression
|
||||
'(("type" "^\\(.*:*.*\\) : " 1)
|
||||
("function" "^\\(.*\\) :: " 1)
|
||||
("struct" "^\\(.*\\) *:: *\\(struct\\)\\(.*\\){" 1)))))
|
||||
|
||||
;; NOTE: taken from the scala-indent package and modified for Jai.
|
||||
;; Still uses the js-indent-line as a base, which will have to be
|
||||
;; replaced when the language is more mature.
|
||||
(defun jai--indent-on-parentheses ()
|
||||
(when (and (= (char-syntax (char-before)) ?\))
|
||||
(= (save-excursion (back-to-indentation) (point)) (1- (point))))
|
||||
(js-indent-line)))
|
||||
|
||||
(defun jai--add-self-insert-hooks ()
|
||||
(add-hook 'post-self-insert-hook
|
||||
'jai--indent-on-parentheses))
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode jai-mode jai-parent-mode "Jai"
|
||||
:syntax-table jai-mode-syntax-table
|
||||
:group 'jai
|
||||
(setq bidi-paragraph-direction 'left-to-right)
|
||||
(setq-local require-final-newline mode-require-final-newline)
|
||||
(setq-local parse-sexp-ignore-comments t)
|
||||
(setq-local comment-start-skip "\\(//+\\|/\\*+\\)\\s *")
|
||||
(setq-local comment-start "//")
|
||||
(setq-local block-comment-start "/*")
|
||||
(setq-local block-comment-end "*/")
|
||||
(setq-local indent-line-function 'js-indent-line)
|
||||
(setq-local font-lock-defaults '(jai-font-lock-defaults))
|
||||
(setq-local beginning-of-defun-function 'jai-beginning-of-defun)
|
||||
(setq-local end-of-defun-function 'jai-end-of-defun)
|
||||
|
||||
;; add indent functionality to some characters
|
||||
(jai--add-self-insert-hooks)
|
||||
|
||||
(font-lock-ensure))
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.jai\\'" . jai-mode))
|
||||
|
||||
(defconst jai--error-regexp
|
||||
"^\\([^ \n:]+.*\.jai\\):\\([0-9]+\\),\\([0-9]+\\):")
|
||||
(push `(jai ,jai--error-regexp 1 2 3 2) compilation-error-regexp-alist-alist)
|
||||
(push 'jai compilation-error-regexp-alist)
|
||||
|
||||
(provide 'jai-mode)
|
||||
;;; jai-mode.el ends here
|
||||
145
.emacs.d/lisp/stupid-indent-mode.el
Executable file
145
.emacs.d/lisp/stupid-indent-mode.el
Executable file
@@ -0,0 +1,145 @@
|
||||
;;; stupid-indent-mode.el --- Plain stupid indentation minor mode
|
||||
|
||||
;; Copyright (C) 2013 Mihai Bazon
|
||||
|
||||
;; Author: Mihai Bazon <mihai.bazon@gmail.com>
|
||||
;; Keywords:
|
||||
|
||||
;; This program 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 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Dumb indentation mode is appropriate for editing buffers that Emacs
|
||||
;; does not fully understand syntactically, such as HTML/PHP
|
||||
;; (typically involving multiple languages with different indentation
|
||||
;; rules in the same buffer). The default indentation level is 2
|
||||
;; (customize `stupid-indent-level').
|
||||
;;
|
||||
;; Key bindings:
|
||||
;;
|
||||
;; TAB -- indent current line by the value of `stupid-indent-level'
|
||||
;; S-TAB -- outdent current line
|
||||
;; C-c TAB -- indent region
|
||||
;; C-c S-TAB -- outdent region
|
||||
;; RET -- newline and indent
|
||||
;; C-c C-TAB -- indent according to mode
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defcustom stupid-indent-level 2
|
||||
"Indentation level for stupid-indent-mode")
|
||||
|
||||
(defun %stupid-force-indent-line ()
|
||||
(let (col)
|
||||
(save-excursion
|
||||
(back-to-indentation)
|
||||
(setq col (+ (current-column) stupid-indent-level))
|
||||
(indent-line-to col))
|
||||
(when (< (current-column) col)
|
||||
(back-to-indentation))))
|
||||
|
||||
(defun stupid-indent-line ()
|
||||
(interactive)
|
||||
(let ((bt (save-excursion
|
||||
(back-to-indentation)
|
||||
(current-column))))
|
||||
(cond
|
||||
((< (current-column) bt)
|
||||
(back-to-indentation))
|
||||
((looking-at "\\s-*\n")
|
||||
(let ((col (save-excursion
|
||||
(previous-line)
|
||||
(back-to-indentation)
|
||||
(current-column))))
|
||||
(if (< (current-column) col)
|
||||
(indent-line-to col)
|
||||
(%stupid-force-indent-line))))
|
||||
(t
|
||||
(%stupid-force-indent-line)))))
|
||||
|
||||
(defun stupid-outdent-line ()
|
||||
(interactive)
|
||||
(let (col)
|
||||
(save-excursion
|
||||
(back-to-indentation)
|
||||
(setq col (- (current-column) stupid-indent-level))
|
||||
(when (>= col 0)
|
||||
(indent-line-to col)))))
|
||||
|
||||
(defun stupid-indent-region (start stop)
|
||||
(interactive "r")
|
||||
(setq stop (copy-marker stop))
|
||||
(goto-char start)
|
||||
(while (< (point) stop)
|
||||
(unless (and (bolp) (eolp))
|
||||
(%stupid-force-indent-line))
|
||||
(forward-line 1)))
|
||||
|
||||
(defun stupid-outdent-region (start stop)
|
||||
(interactive "r")
|
||||
(setq stop (copy-marker stop))
|
||||
(goto-char start)
|
||||
(while (< (point) stop)
|
||||
(unless (and (bolp) (eolp))
|
||||
(stupid-outdent-line))
|
||||
(forward-line 1)))
|
||||
|
||||
(defun stupid-indent ()
|
||||
(interactive)
|
||||
(if (use-region-p)
|
||||
(save-excursion
|
||||
(stupid-indent-region (region-beginning) (region-end))
|
||||
(setq deactivate-mark nil))
|
||||
(stupid-indent-line)))
|
||||
|
||||
(defun stupid-outdent ()
|
||||
(interactive)
|
||||
(if (use-region-p)
|
||||
(save-excursion
|
||||
(stupid-outdent-region (region-beginning) (region-end))
|
||||
(setq deactivate-mark nil))
|
||||
(stupid-outdent-line)))
|
||||
|
||||
(defun stupid-indent-newline ()
|
||||
(interactive)
|
||||
(when (< (point)
|
||||
(save-excursion
|
||||
(back-to-indentation)
|
||||
(point)))
|
||||
(back-to-indentation))
|
||||
(let ((col (save-excursion
|
||||
(back-to-indentation)
|
||||
(current-column))))
|
||||
(newline)
|
||||
(indent-to-column col)))
|
||||
|
||||
(define-minor-mode stupid-indent-mode
|
||||
"Stupid indent mode is just plain stupid."
|
||||
:init-value nil
|
||||
:lighter "/SI"
|
||||
:global nil
|
||||
:keymap `(
|
||||
(,(kbd "<tab>") . stupid-indent)
|
||||
(,(kbd "<backtab>") . stupid-outdent)
|
||||
(,(kbd "C-c <tab>") . stupid-indent-region)
|
||||
(,(kbd "C-c <backtab>") . stupid-outdent-region)
|
||||
(,(kbd "<return>") . stupid-indent-newline)
|
||||
(,(kbd "C-c C-<tab>") . indent-according-to-mode)
|
||||
)
|
||||
(when stupid-indent-mode
|
||||
(add-hook 'write-contents-functions
|
||||
'delete-trailing-whitespace)))
|
||||
|
||||
(provide 'stupid-indent-mode)
|
||||
;;; stupid-indent-mode.el ends here
|
||||
15046
.emacs.d/lisp/web-mode.el
Executable file
15046
.emacs.d/lisp/web-mode.el
Executable file
File diff suppressed because it is too large
Load Diff
731
.emacs.d/lisp/xah-find.el
Executable file
731
.emacs.d/lisp/xah-find.el
Executable file
@@ -0,0 +1,731 @@
|
||||
;;; xah-find.el --- find replace in pure emacs lisp. Purpose similar to grep/sed. -*- coding: utf-8; lexical-binding: t; -*-
|
||||
|
||||
;; Copyright © 2012-2021 by Xah Lee
|
||||
|
||||
;; Author: Xah Lee ( http://xahlee.info/ )
|
||||
;; Version: 5.4.20211014135145
|
||||
;; Created: 02 April 2012
|
||||
;; Package-Requires: ((emacs "24.1"))
|
||||
;; Keywords: convenience, extensions, files, tools, unix
|
||||
;; License: GPL v3
|
||||
;; Homepage: http://ergoemacs.org/emacs/elisp-xah-find-text.html
|
||||
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Provides emacs commands for find/replace text of files in a directory, written entirely in emacs lisp.
|
||||
|
||||
;; This package provides these commands:
|
||||
|
||||
;; xah-find-text
|
||||
;; xah-find-text-regex
|
||||
;; xah-find-count
|
||||
;; xah-find-replace-text
|
||||
;; xah-find-replace-text-regex
|
||||
|
||||
;; • Pure emacs lisp. No dependencies on unix/linux grep/sed/find. Especially useful on Windows.
|
||||
|
||||
;; • Output is highlighted and clickable for jumping to occurrence.
|
||||
|
||||
;; • Using emacs regex, not bash/perl etc regex.
|
||||
|
||||
;; These commands treats find/replace string as sequence of chars, not as lines as in grep/sed, so it's easier to find or replace a text containing lots newlines, especially programming language source code.
|
||||
|
||||
;; • Reliably Find/Replace string that contains newline chars.
|
||||
|
||||
;; • Reliably Find/Replace string that contains lots Unicode chars. See http://xahlee.info/comp/unix_uniq_unicode_bug.html and http://ergoemacs.org/emacs/emacs_grep_problem.html
|
||||
|
||||
;; • Reliably Find/Replace string that contains lots escape slashes or backslashes. For example, regex in source code, Microsoft Windows' path.
|
||||
|
||||
;; The result output is also not based on lines. Instead, visual separators are used for easy reading.
|
||||
|
||||
;; For each occurrence or replacement, n chars will be printed before and after. The number of chars to show is defined by `xah-find-context-char-count-before' and `xah-find-context-char-count-after'
|
||||
|
||||
;; Each “block of text” in output is one occurrence.
|
||||
;; For example, if a line in a file has 2 occurrences, then the same line will be reported twice, as 2 “blocks”.
|
||||
;; so, the number of blocks corresponds exactly to the number of occurrences.
|
||||
|
||||
;; Keys
|
||||
;; -----------------------
|
||||
;; TAB xah-find-next-match
|
||||
;; <backtab> xah-find-previous-match
|
||||
|
||||
;; RET xah-find--jump-to-place
|
||||
;; <mouse-1> xah-find--mouse-jump-to-place
|
||||
|
||||
;; <left> xah-find-previous-match
|
||||
;; <right> xah-find-next-match
|
||||
|
||||
;; <down> xah-find-next-file
|
||||
;; <up> xah-find-previous-file
|
||||
|
||||
;; M-n xah-find-next-file
|
||||
;; M-p xah-find-previous-file
|
||||
|
||||
;; IGNORE DIRECTORIES
|
||||
|
||||
;; By default, .git dir is ignored. You can add to it by adding the following in your init:
|
||||
|
||||
;; (setq
|
||||
;; xah-find-dir-ignore-regex-list
|
||||
;; [
|
||||
;; "\\.git/"
|
||||
;; ; more regex here. regex is matched against file full path
|
||||
;; ])
|
||||
|
||||
;; USE CASE
|
||||
|
||||
;; To give a idea what file size, number of files, are practical, here's my typical use pattern:
|
||||
;; • 5 thousand HTML files match file name regex.
|
||||
;; • Each HTML file size are usually less than 200k bytes.
|
||||
;; • search string length have been up to 13 lines of text.
|
||||
|
||||
;; Homepage: http://ergoemacs.org/emacs/elisp-xah-find-text.html
|
||||
|
||||
;; Like it?
|
||||
;; Buy Xah Emacs Tutorial
|
||||
;; http://ergoemacs.org/emacs/buy_xah_emacs_tutorial.html
|
||||
;; Thank you.
|
||||
|
||||
;;; INSTALL
|
||||
|
||||
;; To install manually, place this file in the directory [~/.emacs.d/lisp/]
|
||||
|
||||
;; Then, place the following code in your emacs init file
|
||||
|
||||
;; (add-to-list 'load-path "~/.emacs.d/lisp/")
|
||||
;; (autoload 'xah-find-text "xah-find" "find replace" t)
|
||||
;; (autoload 'xah-find-text-regex "xah-find" "find replace" t)
|
||||
;; (autoload 'xah-find-replace-text "xah-find" "find replace" t)
|
||||
;; (autoload 'xah-find-replace-text-regex "xah-find" "find replace" t)
|
||||
;; (autoload 'xah-find-count "xah-find" "find replace" t)
|
||||
|
||||
;;; HISTORY
|
||||
|
||||
;; version 2.1.0, 2015-05-30 Complete rewrite.
|
||||
;; version 1.0, 2012-04-02 First version.
|
||||
|
||||
;;; CONTRIBUTOR
|
||||
;; 2015-12-09 Peter Buckley (dx-pbuckley). defcustom for result highlight color.
|
||||
|
||||
;; HHH___________________________________________________________________
|
||||
;;; Code:
|
||||
|
||||
(require 'ido)
|
||||
(require 'seq)
|
||||
|
||||
(ido-common-initialization)
|
||||
;; 2015-07-26 else, when ido-read-directory-name is called, Return key insert line return instead of submit. For some reason i dunno.
|
||||
|
||||
(defvar xah-find-context-char-count-before 100 "Number of characters to print before search string." )
|
||||
|
||||
(defvar xah-find-context-char-count-after 50 "Number of characters to print after search string." )
|
||||
|
||||
(defvar xah-find-dir-ignore-regex-list
|
||||
[
|
||||
"\\.git/"
|
||||
]
|
||||
"A list or vector of regex patterns, if match, that directory will be ignored.
|
||||
The regex match is Case Insensitive."
|
||||
)
|
||||
|
||||
(defface xah-find-file-path-highlight
|
||||
'((t :foreground "black"
|
||||
:background "pink"
|
||||
))
|
||||
"Face of file path where a text match is found."
|
||||
:group 'xah-find
|
||||
)
|
||||
|
||||
(defface xah-find-match-highlight
|
||||
'((t :foreground "black"
|
||||
:background "yellow"
|
||||
))
|
||||
"Face for matched text."
|
||||
:group 'xah-find
|
||||
)
|
||||
|
||||
(defface xah-find-replace-highlight
|
||||
'((t :foreground "black"
|
||||
:background "green"
|
||||
))
|
||||
"Face for replaced text."
|
||||
:group 'xah-find
|
||||
)
|
||||
|
||||
(defvar xah-find-file-separator
|
||||
"ff━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"
|
||||
"A string as visual separator."
|
||||
)
|
||||
|
||||
(defvar xah-find-occur-separator
|
||||
"oo────────────────────────────────────────────────────────────\n\n"
|
||||
"A string as visual separator."
|
||||
)
|
||||
|
||||
(defvar xah-find-occur-prefix "〖" "A left-bracket string that marks matched text and navigate previous/next. This string should basically never occure in your files. If it does, jumping to the location may not work." )
|
||||
|
||||
(defvar xah-find-occur-postfix "〗" "A right-bracket string that marks matched text and navigate previous/next. See also `xah-find-occur-prefix'." )
|
||||
|
||||
(defvar xah-find-replace-prefix "『" "A left-bracket string that marks matched text and navigate previous/next. See also `xah-find-occur-prefix'." )
|
||||
|
||||
(defvar xah-find-replace-postfix "』" "A right-bracket string that marks matched text and navigate previous/next. See also `xah-find-occur-prefix'." )
|
||||
|
||||
;; more brackets at http://xahlee.info/comp/unicode_matching_brackets.html
|
||||
|
||||
(defvar xah-find-filepath-prefix "〘" "A left-bracket string used to mark file path and navigate previous/next. See also `xah-find-occur-prefix'." )
|
||||
|
||||
(defvar xah-find-filepath-postfix "〙" "A right-bracket string used to mark file path and navigate previous/next. See also `xah-find-occur-prefix'." )
|
||||
|
||||
(defvar xah-find-pos-prefix "⁅" "A string of left bracket that marks line column position of occurrence. See also `xah-find-occur-prefix'." )
|
||||
|
||||
(defvar xah-find-pos-postfix "⁆" "A string of right bracket that marks line column position of occurrence. See also `xah-find-occur-prefix'." )
|
||||
|
||||
;; HHH___________________________________________________________________
|
||||
|
||||
(defvar xah-find-file-path-regex-history '() "File path regex history list, used by `xah-find-text' and others.")
|
||||
|
||||
(defun xah-find--ignore-dir-p (Path)
|
||||
"Return true if one of `xah-find-dir-ignore-regex-list' matches PATH. Else, nil.
|
||||
version 2016-11-16 2021-10-11"
|
||||
(let ((case-fold-search t))
|
||||
(catch 'exit25001
|
||||
(mapc
|
||||
(lambda ($regex)
|
||||
(when (string-match $regex Path) (throw 'exit25001 $regex)))
|
||||
xah-find-dir-ignore-regex-list)
|
||||
nil
|
||||
)))
|
||||
|
||||
;; HHH___________________________________________________________________
|
||||
(defvar xah-find-output-mode-map nil "Keybinding for `xah-find.el output'")
|
||||
(progn
|
||||
(setq xah-find-output-mode-map (make-sparse-keymap))
|
||||
|
||||
(define-key xah-find-output-mode-map (kbd "<left>") 'xah-find-previous-match)
|
||||
(define-key xah-find-output-mode-map (kbd "<right>") 'xah-find-next-match)
|
||||
(define-key xah-find-output-mode-map (kbd "<down>") 'xah-find-next-file)
|
||||
(define-key xah-find-output-mode-map (kbd "<up>") 'xah-find-previous-file)
|
||||
|
||||
(define-key xah-find-output-mode-map (kbd "TAB") 'xah-find-next-match)
|
||||
(define-key xah-find-output-mode-map (kbd "<backtab>") 'xah-find-previous-match)
|
||||
(define-key xah-find-output-mode-map (kbd "<mouse-1>") 'xah-find--mouse-jump-to-place)
|
||||
(define-key xah-find-output-mode-map (kbd "M-n") 'xah-find-next-file)
|
||||
(define-key xah-find-output-mode-map (kbd "M-p") 'xah-find-previous-file)
|
||||
(define-key xah-find-output-mode-map (kbd "RET") 'xah-find--jump-to-place)
|
||||
)
|
||||
|
||||
(defvar xah-find-output-syntax-table nil "Syntax table for `xah-find-output-mode'.")
|
||||
|
||||
(setq xah-find-output-syntax-table
|
||||
(let ( (synTable (make-syntax-table)))
|
||||
(modify-syntax-entry ?\" "." synTable)
|
||||
;; (modify-syntax-entry ?〖 "(〗" synTable)
|
||||
;; (modify-syntax-entry ?〗 "(〖" synTable)
|
||||
synTable))
|
||||
|
||||
(setq xah-find-font-lock-keywords
|
||||
(let (
|
||||
(xMatch (format "%s\\([^%s]+\\)%s" xah-find-occur-prefix xah-find-occur-postfix xah-find-occur-postfix))
|
||||
|
||||
(xRep (format "%s\\([^%s]+\\)%s" xah-find-replace-prefix xah-find-replace-postfix xah-find-replace-postfix))
|
||||
(xfPath (format "%s\\([^%s]+\\)%s" xah-find-filepath-prefix xah-find-filepath-postfix xah-find-filepath-postfix)))
|
||||
|
||||
`(
|
||||
(,xMatch . (1 'xah-find-match-highlight))
|
||||
(,xRep . (1 'xah-find-replace-highlight))
|
||||
(,xfPath . (1 'xah-find-file-path-highlight)))))
|
||||
|
||||
(define-derived-mode xah-find-output-mode fundamental-mode "∑xah-find"
|
||||
"Major mode for reading output for xah-find commands.
|
||||
home page:
|
||||
URL `http://ergoemacs.org/emacs/elisp-xah-find-text.html'
|
||||
|
||||
\\{xah-find-output-mode-map}
|
||||
Version 2021-06-23"
|
||||
(setq font-lock-defaults '((xah-find-font-lock-keywords)))
|
||||
(set-syntax-table xah-find-output-syntax-table))
|
||||
|
||||
(defun xah-find-next-match ()
|
||||
"Put cursor to next occurrence."
|
||||
(interactive)
|
||||
(search-forward xah-find-occur-prefix nil t ))
|
||||
|
||||
(defun xah-find-previous-match ()
|
||||
"Put cursor to previous occurrence."
|
||||
(interactive)
|
||||
(search-backward xah-find-occur-postfix nil t ))
|
||||
|
||||
(defun xah-find-next-file ()
|
||||
"Put cursor to next file."
|
||||
(interactive)
|
||||
(search-forward xah-find-filepath-prefix nil t ))
|
||||
|
||||
(defun xah-find-previous-file ()
|
||||
"Put cursor to previous file."
|
||||
(interactive)
|
||||
(search-backward xah-find-filepath-postfix nil t ))
|
||||
|
||||
(defun xah-find--mouse-jump-to-place (Event)
|
||||
"Open file and put cursor at location of the occurrence.
|
||||
Version 2016-12-18"
|
||||
(interactive "e")
|
||||
(let* (
|
||||
($pos (posn-point (event-end Event)))
|
||||
($fpath (get-text-property $pos 'xah-find-fpath))
|
||||
($posJumpTo (get-text-property $pos 'xah-find-pos)))
|
||||
(when $fpath
|
||||
(progn
|
||||
(find-file-other-window $fpath)
|
||||
(when $posJumpTo (goto-char $posJumpTo))))))
|
||||
|
||||
;; (defun xah-find--jump-to-place ()
|
||||
;; "Open file and put cursor at location of the occurrence.
|
||||
;; Version 2017-04-07"
|
||||
;; (interactive)
|
||||
;; (let (($fpath (get-text-property (point) 'xah-find-fpath))
|
||||
;; ($posJumpTo (get-text-property (point) 'xah-find-pos)))
|
||||
;; (if $fpath
|
||||
;; (if (file-exists-p $fpath)
|
||||
;; (progn
|
||||
;; (find-file-other-window $fpath)
|
||||
;; (when $posJumpTo (goto-char $posJumpTo)))
|
||||
;; (error "File at 「%s」 does not exist." $fpath))
|
||||
;; (insert "\n"))))
|
||||
|
||||
(defun xah-find--jump-to-place ()
|
||||
"Open file and put cursor at location of the occurrence.
|
||||
Version 2019-03-14"
|
||||
(interactive)
|
||||
(let (($fpath (get-text-property (point) 'xah-find-fpath))
|
||||
($posJumpTo (get-text-property (point) 'xah-find-pos))
|
||||
($p0 (point))
|
||||
$p1 $p2
|
||||
)
|
||||
(if $fpath
|
||||
(if (file-exists-p $fpath)
|
||||
(progn
|
||||
(find-file-other-window $fpath)
|
||||
(when $posJumpTo (goto-char $posJumpTo)))
|
||||
(error "File at 「%s」 does not exist." $fpath))
|
||||
(progn
|
||||
(save-excursion
|
||||
(goto-char $p0)
|
||||
|
||||
;; (if (eq (char-after (line-beginning-position)) (string-to-char xah-find-filepath-prefix ))
|
||||
;; (progn )
|
||||
;; (progn ))
|
||||
|
||||
(search-forward xah-find-file-separator)
|
||||
(search-backward xah-find-filepath-prefix )
|
||||
(setq $p1 (1+ (point)))
|
||||
(search-forward xah-find-filepath-postfix)
|
||||
(setq $p2 (1- (point)))
|
||||
(setq $fpath (buffer-substring-no-properties $p1 $p2))
|
||||
|
||||
(progn
|
||||
(goto-char $p0)
|
||||
(if (search-backward xah-find-pos-prefix nil t)
|
||||
(progn
|
||||
(setq $p1 (1+ (point)))
|
||||
(search-forward xah-find-pos-postfix )
|
||||
(setq $p2 (1- (point)))
|
||||
(setq $posJumpTo (string-to-number (buffer-substring-no-properties $p1 $p2))))
|
||||
(setq $posJumpTo nil))))
|
||||
(if (file-exists-p $fpath)
|
||||
(progn
|
||||
(find-file-other-window $fpath)
|
||||
(when $posJumpTo (goto-char $posJumpTo)))
|
||||
(error "File at 「%s」 does not exist." $fpath))))))
|
||||
|
||||
;; HHH___________________________________________________________________
|
||||
(defun xah-find--backup-suffix (S)
|
||||
"Return a string of the form 「~‹S›~‹date time stamp›~」"
|
||||
(concat "~" S (format-time-string "%Y%m%dT%H%M%S") "~"))
|
||||
|
||||
(defun xah-find--current-date-time-string ()
|
||||
"Return current date-time string in this format 「2012-04-05T21:08:24-07:00」"
|
||||
(concat
|
||||
(format-time-string "%Y-%m-%dT%T")
|
||||
(funcall (lambda (x) (format "%s:%s" (substring x 0 3) (substring x 3 5))) (format-time-string "%z"))))
|
||||
|
||||
(defun xah-find--print-header (BufferObj Cmd InputDir PathRegex SearchStr &optional ReplaceStr Write-file-p BackupQ)
|
||||
"Print things"
|
||||
(princ
|
||||
(concat
|
||||
"-*- coding: utf-8; mode: xah-find-output -*-" "\n"
|
||||
"Datetime: " (xah-find--current-date-time-string) "\n"
|
||||
"Result of: " Cmd "\n"
|
||||
(format "Directory: %s\n" InputDir )
|
||||
(format "Path regex: %s\n" PathRegex )
|
||||
(format "Write to file: %s\n" Write-file-p )
|
||||
(format "Backup: %s\n" BackupQ )
|
||||
(format "Search string: %s\n" SearchStr )
|
||||
(when ReplaceStr (format "Replace string [[%s]]\n" ReplaceStr))
|
||||
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n"
|
||||
)
|
||||
BufferObj))
|
||||
|
||||
(defun xah-find--occur-output (P1 P2 Fpath Buff &optional NoContextString-p AltColor)
|
||||
"Print result to a output buffer, with text properties (e.g. highlight and link).
|
||||
P1 P2 are region boundary. Region of current buffer are grabbed. The region typically is the searched text.
|
||||
Fpath is file path to be used as property value for clickable link.
|
||||
Buff is the buffer to insert P1 P2 region.
|
||||
NoContextString-p if true, don't add text before and after the region of interest. Else, `xah-find-context-char-count-before' number of chars are inserted before, and similar for `xah-find-context-char-count-after'.
|
||||
AltColor if true, use a different highlight color face `xah-find-replace-highlight'. Else, use `xah-find-match-highlight'.
|
||||
Version 2017-04-07 2021-08-05"
|
||||
(let* (
|
||||
($begin (max 1 (- P1 xah-find-context-char-count-before )))
|
||||
($end (min (point-max) (+ P2 xah-find-context-char-count-after )))
|
||||
($textBefore (if NoContextString-p "" (buffer-substring-no-properties $begin P1 )))
|
||||
$textMiddle
|
||||
($textAfter (if NoContextString-p "" (buffer-substring-no-properties P2 $end)))
|
||||
($face (if AltColor 'xah-find-replace-highlight 'xah-find-match-highlight))
|
||||
$bracketL $bracketR
|
||||
)
|
||||
(put-text-property P1 P2 'face $face)
|
||||
(put-text-property P1 P2 'xah-find-fpath Fpath)
|
||||
(put-text-property P1 P2 'xah-find-pos P1)
|
||||
(add-text-properties P1 P2 '(mouse-face highlight))
|
||||
(setq $textMiddle (buffer-substring P1 P2 ))
|
||||
(if AltColor
|
||||
(setq $bracketL xah-find-replace-prefix $bracketR xah-find-replace-postfix )
|
||||
(setq $bracketL xah-find-occur-prefix $bracketR xah-find-occur-postfix ))
|
||||
(with-current-buffer Buff
|
||||
(insert
|
||||
(format "%s%s%s\n" xah-find-pos-prefix P1 xah-find-pos-postfix)
|
||||
$textBefore
|
||||
$bracketL
|
||||
$textMiddle
|
||||
$bracketR
|
||||
$textAfter
|
||||
"\n"
|
||||
xah-find-occur-separator ))))
|
||||
|
||||
;; (defun xah-find--print-replace-block (P1 P2 Buff)
|
||||
;; "print "
|
||||
;; (princ (concat "❬" (buffer-substring-no-properties P1 P2 ) "❭" "\n" xah-find-occur-separator) Buff))
|
||||
|
||||
(defun xah-find--print-file-count (Filepath4287 Count8086 BuffObj32)
|
||||
"Print file path and count"
|
||||
(princ (format "%d %s%s%s\n%s"
|
||||
Count8086
|
||||
xah-find-filepath-prefix
|
||||
Filepath4287
|
||||
xah-find-filepath-postfix
|
||||
xah-find-file-separator)
|
||||
BuffObj32))
|
||||
|
||||
(defun xah-find--switch-to-output (Buffer)
|
||||
"switch to Buffer and highlight stuff"
|
||||
(let ($p3 $p4)
|
||||
(switch-to-buffer Buffer)
|
||||
(progn
|
||||
(goto-char (point-min))
|
||||
(while (search-forward xah-find-filepath-prefix nil t)
|
||||
(setq $p3 (point))
|
||||
(search-forward xah-find-filepath-postfix nil nil)
|
||||
(setq $p4 (match-beginning 0))
|
||||
(put-text-property $p3 $p4 'xah-find-fpath (buffer-substring-no-properties $p3 $p4))
|
||||
(add-text-properties $p3 $p4 '(mouse-face highlight))
|
||||
(put-text-property (line-beginning-position) (line-end-position) 'face 'xah-find-file-path-highlight)))
|
||||
|
||||
(goto-char (point-min))
|
||||
(search-forward "━" nil t) ; todo, need fix
|
||||
(search-forward xah-find-occur-prefix nil t)
|
||||
(xah-find-output-mode)
|
||||
))
|
||||
|
||||
;; HHH___________________________________________________________________
|
||||
|
||||
(defun xah-find--get-fpath-regex (&optional DefaultExt)
|
||||
"Returns a string, that is a regex to match a file extension.
|
||||
The result is based on current buffer's file extension.
|
||||
If current file doesn't have extension or current buffer isn't a file, then extension DefaultExt is used.
|
||||
DefaultExt should be a string, without dot, such as 「\"html\"」.
|
||||
If DefaultExt is nil, 「\"html\"」 is used.
|
||||
Example return value: 「ββ.htmlββ'」, where β is a backslash.
|
||||
"
|
||||
(let (
|
||||
($buff-is-file-p (buffer-file-name))
|
||||
$fname-ext
|
||||
$default-ext
|
||||
)
|
||||
(setq $default-ext (if (null DefaultExt)
|
||||
(progn "html")
|
||||
(progn DefaultExt)))
|
||||
(if $buff-is-file-p
|
||||
(progn
|
||||
(setq $fname-ext (file-name-extension (buffer-file-name)))
|
||||
(if (or (null $fname-ext) (equal $fname-ext ""))
|
||||
(progn (concat "\\." $default-ext "$"))
|
||||
(progn (concat "\\." $fname-ext "$"))))
|
||||
(progn (concat "\\." $default-ext "$")))))
|
||||
|
||||
;;;###autoload
|
||||
(defun xah-find-count (SearchStr CountExpr CountNumber InputDir PathRegex)
|
||||
"Report how many occurrences of a string, of a given dir.
|
||||
Similar to `rgrep', but written in pure elisp.
|
||||
Result is shown in buffer *xah-find output*.
|
||||
Case sensitivity is determined by `case-fold-search'. Call `toggle-case-fold-search' to change.
|
||||
`xah-find-dir-ignore-regex-list' is respected.
|
||||
\\{xah-find-output-mode-map}
|
||||
|
||||
Version 2021-10-11"
|
||||
(interactive
|
||||
(let ( $operator)
|
||||
(list
|
||||
(read-string (format "Search string (default %s): " (current-word)) nil 'query-replace-history (current-word))
|
||||
(setq $operator (ido-completing-read "Report on: " '("greater than" "greater or equal to" "equal" "not equal" "less than" "less or equal to" )))
|
||||
(read-string (format "Count %s: " $operator) "0")
|
||||
(ido-read-directory-name "Directory: " default-directory default-directory "MUSTMATCH")
|
||||
(read-from-minibuffer "File path regex: " (xah-find--get-fpath-regex "el") nil nil 'dired-regexp-history))))
|
||||
(let* (($outBufName "*xah-find output*")
|
||||
$outBuffer
|
||||
($countOperator
|
||||
(cond
|
||||
((string-equal "less than" CountExpr ) '<)
|
||||
((string-equal "less or equal to" CountExpr ) '<=)
|
||||
((string-equal "greater than" CountExpr ) '>)
|
||||
((string-equal "greater or equal to" CountExpr ) '>=)
|
||||
((string-equal "equal" CountExpr ) '=)
|
||||
((string-equal "not equal" CountExpr ) '/=)
|
||||
(t (error "count expression 「%s」 is wrong!" CountExpr ))))
|
||||
($countNumber (string-to-number CountNumber)))
|
||||
(when (get-buffer $outBufName) (kill-buffer $outBufName))
|
||||
(setq $outBuffer (generate-new-buffer $outBufName))
|
||||
(xah-find--print-header $outBuffer "xah-find-count" InputDir PathRegex SearchStr )
|
||||
(mapc
|
||||
(lambda ($f)
|
||||
(let (($count 0))
|
||||
(with-temp-buffer
|
||||
(insert-file-contents $f)
|
||||
(goto-char (point-min))
|
||||
(while (search-forward SearchStr nil t) (setq $count (1+ $count)))
|
||||
(when (funcall $countOperator $count $countNumber)
|
||||
(xah-find--print-file-count $f $count $outBuffer)))))
|
||||
(seq-filter (lambda (x) (not (xah-find--ignore-dir-p x)))
|
||||
(directory-files-recursively InputDir PathRegex)))
|
||||
(princ "Done." $outBuffer)
|
||||
(xah-find--switch-to-output $outBuffer)))
|
||||
|
||||
;;;###autoload
|
||||
(defun xah-find-text (SearchStr InputDir PathRegex FixedCaseSearchQ PrintContext-p)
|
||||
"Report files that contain string.
|
||||
By default, not case sensitive, and print surrounding text.
|
||||
If `universal-argument' is called first, prompt to ask.
|
||||
`xah-find-dir-ignore-regex-list' is respected.
|
||||
Result is shown in buffer *xah-find output*.
|
||||
\\{xah-find-output-mode-map}
|
||||
|
||||
version 2021-10-11"
|
||||
(interactive
|
||||
(let (($defaultInput (if (region-active-p) (buffer-substring-no-properties (region-beginning) (region-end)) (current-word))))
|
||||
(list
|
||||
(read-string (format "Search string (default %s): " $defaultInput) nil 'query-replace-history $defaultInput)
|
||||
(ido-read-directory-name "Directory: " default-directory default-directory "MUSTMATCH")
|
||||
(read-from-minibuffer "File path regex: " (xah-find--get-fpath-regex "html") nil nil 'dired-regexp-history)
|
||||
(if current-prefix-arg (y-or-n-p "Fixed case in search?") nil )
|
||||
(if current-prefix-arg (y-or-n-p "Print surrounding Text?") t ))))
|
||||
(let* ((case-fold-search (not FixedCaseSearchQ))
|
||||
($count 0)
|
||||
($outBufName "*xah-find output*")
|
||||
$outBuffer
|
||||
)
|
||||
(setq InputDir (file-name-as-directory InputDir)) ; normalize dir path
|
||||
(when (get-buffer $outBufName) (kill-buffer $outBufName))
|
||||
(setq $outBuffer (generate-new-buffer $outBufName))
|
||||
(xah-find--print-header $outBuffer "xah-find-text" InputDir PathRegex SearchStr )
|
||||
(mapc
|
||||
(lambda ($path)
|
||||
(setq $count 0)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents $path)
|
||||
(while (search-forward SearchStr nil t)
|
||||
(setq $count (1+ $count))
|
||||
(when PrintContext-p (xah-find--occur-output (match-beginning 0) (match-end 0) $path $outBuffer)))
|
||||
(when (> $count 0) (xah-find--print-file-count $path $count $outBuffer))))
|
||||
(seq-filter (lambda (x) (not (xah-find--ignore-dir-p x)))
|
||||
(directory-files-recursively InputDir PathRegex)))
|
||||
(princ "Done." $outBuffer)
|
||||
(xah-find--switch-to-output $outBuffer)))
|
||||
|
||||
(defun xah-find-count-slash (Path)
|
||||
"Count the number of slash in path.
|
||||
Useful for finding the level of a nested dir.
|
||||
Note: you should probably call `expand-file-name' on Path first to canonize path, to make sure dir name always ends in slash.
|
||||
Version 2021-10-11"
|
||||
(interactive)
|
||||
(seq-count (lambda (x) (char-equal x ?/)) Path))
|
||||
|
||||
;;;###autoload
|
||||
(defun xah-find-replace-text (SearchStr ReplaceStr InputDir PathRegex DepthMin DepthMax WriteToFileQ FixedCaseSearchQ FixedCaseReplaceQ BackupQ)
|
||||
"Find/Replace string in all files of a directory.
|
||||
Search string can span multiple lines.
|
||||
Search string is not regex.
|
||||
`xah-find-dir-ignore-regex-list' is respected.
|
||||
|
||||
Backup, if requested, backup filenames has suffix with timestamp, like this: ~xf20150531T233826~
|
||||
|
||||
Result is shown in buffer *xah-find output*.
|
||||
\\{xah-find-output-mode-map}
|
||||
|
||||
version 2021-10-11"
|
||||
(interactive
|
||||
(let (($searchStr (read-string (format "Search string (default %s): " (current-word)) nil 'query-replace-history (current-word)))
|
||||
($replaceStr (read-string "Replace string: " nil 'query-replace-history))
|
||||
($inputDir (ido-read-directory-name "Directory: " default-directory default-directory "MUSTMATCH"))
|
||||
($pathRegex (read-from-minibuffer "File path regex: " (xah-find--get-fpath-regex "el") nil nil 'dired-regexp-history))
|
||||
;; ($recurseQ (yes-or-no-p "Recurse to subdirs?"))
|
||||
($depthMin (read-number "Min dir depth. Start dir has depth 0:" 0))
|
||||
($depthMax (read-number "Max dir depth. (max+1 depth subdir files are excluded):" 9))
|
||||
($writeToFileQ (y-or-n-p "Write changes to file?"))
|
||||
($fixedCaseSearchQ (y-or-n-p "Fixed case in search?"))
|
||||
($fixedCaseReplaceQ (y-or-n-p "Fixed case in replacement?"))
|
||||
($backupQ (y-or-n-p "Make backup?")))
|
||||
(list $searchStr $replaceStr $inputDir $pathRegex
|
||||
$depthMin $depthMax
|
||||
$writeToFileQ $fixedCaseSearchQ $fixedCaseReplaceQ $backupQ)))
|
||||
(let (($outBufName "*xah-find output*")
|
||||
$outBuffer
|
||||
($backupSuffix (xah-find--backup-suffix "xf"))
|
||||
($rootDepth (xah-find-count-slash (expand-file-name InputDir))))
|
||||
(when (get-buffer $outBufName) (kill-buffer $outBufName))
|
||||
(setq $outBuffer (generate-new-buffer $outBufName))
|
||||
(xah-find--print-header $outBuffer "xah-find-replace-text" InputDir PathRegex SearchStr ReplaceStr WriteToFileQ BackupQ)
|
||||
(mapc
|
||||
(lambda ($f)
|
||||
(let ((case-fold-search (not FixedCaseSearchQ))
|
||||
($count 0))
|
||||
(with-temp-buffer
|
||||
(insert-file-contents $f)
|
||||
(while (search-forward SearchStr nil t)
|
||||
(setq $count (1+ $count))
|
||||
(replace-match ReplaceStr FixedCaseReplaceQ "literalreplace")
|
||||
(xah-find--occur-output (match-beginning 0) (point) $f $outBuffer))
|
||||
(when (> $count 0)
|
||||
(when WriteToFileQ
|
||||
(when BackupQ (copy-file $f (concat $f $backupSuffix) t))
|
||||
(write-region (point-min) (point-max) $f nil 3))
|
||||
(xah-find--print-file-count $f $count $outBuffer)))))
|
||||
(seq-filter
|
||||
(lambda (x)
|
||||
(let (($df (- (xah-find-count-slash x) $rootDepth)))
|
||||
(and (>= $df DepthMin) (<= $df DepthMax))))
|
||||
(directory-files-recursively InputDir PathRegex)))
|
||||
(princ "Done." $outBuffer)
|
||||
(xah-find--switch-to-output $outBuffer)))
|
||||
|
||||
;;;###autoload
|
||||
(defun xah-find-text-regex (SearchRegex InputDir PathRegex RecurseQ FixedCaseSearchQ PrintContextLevel)
|
||||
"Report files that contain a string pattern, similar to `rgrep'.
|
||||
Result is shown in buffer *xah-find output*.
|
||||
`xah-find-dir-ignore-regex-list' is respected.
|
||||
|
||||
\\{xah-find-output-mode-map}
|
||||
Version 2016-12-21 2021-10-11"
|
||||
(interactive
|
||||
(list
|
||||
(read-string (format "Search regex (default %s): " (current-word)) nil 'query-replace-history (current-word))
|
||||
(ido-read-directory-name "Directory: " default-directory default-directory "MUSTMATCH")
|
||||
(read-from-minibuffer "File path regex: " (xah-find--get-fpath-regex "el") nil nil 'dired-regexp-history)
|
||||
(yes-or-no-p "Recurse to subdirs?")
|
||||
(y-or-n-p "Fixed case search?")
|
||||
(ido-completing-read "Print context level: " '("with context string" "just matched pattern" "none"))))
|
||||
(let (($count 0)
|
||||
($outBufName "*xah-find output*")
|
||||
$outBuffer
|
||||
)
|
||||
(setq InputDir (file-name-as-directory InputDir)) ; add ending slash
|
||||
(when (get-buffer $outBufName) (kill-buffer $outBufName))
|
||||
(setq $outBuffer (generate-new-buffer $outBufName))
|
||||
(xah-find--print-header $outBuffer "xah-find-text-regex" InputDir PathRegex SearchRegex)
|
||||
(mapc
|
||||
(lambda ($fp)
|
||||
(setq $count 0)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents $fp)
|
||||
(setq case-fold-search (not FixedCaseSearchQ))
|
||||
(while (re-search-forward SearchRegex nil t)
|
||||
(setq $count (1+ $count))
|
||||
(cond
|
||||
((equal PrintContextLevel "none") nil)
|
||||
((equal PrintContextLevel "just matched pattern")
|
||||
(xah-find--occur-output (match-beginning 0) (match-end 0) $fp $outBuffer t))
|
||||
((equal PrintContextLevel "with context string")
|
||||
(xah-find--occur-output (match-beginning 0) (match-end 0) $fp $outBuffer))))
|
||||
(when (> $count 0) (xah-find--print-file-count $fp $count $outBuffer))))
|
||||
(seq-filter (lambda (x) (not (xah-find--ignore-dir-p x)))
|
||||
(if RecurseQ
|
||||
(directory-files-recursively InputDir PathRegex)
|
||||
(directory-files InputDir t PathRegex))))
|
||||
(princ "Done." $outBuffer)
|
||||
(xah-find--switch-to-output $outBuffer)))
|
||||
|
||||
;;;###autoload
|
||||
(defun xah-find-replace-text-regex (Regex ReplaceStr InputDir PathRegex WriteToFileQ FixedCaseSearchQ FixedCaseReplaceQ ShowcontexQ BackupQ)
|
||||
"Find/Replace by regex in all files of a directory.
|
||||
|
||||
`xah-find-dir-ignore-regex-list' is respected.
|
||||
|
||||
Backup, if requested, backup filenames has suffix with timestamp, like this: ~xf20150531T233826~
|
||||
|
||||
When called in lisp code:
|
||||
Regex is a regex pattern.
|
||||
ReplaceStr is replacement string.
|
||||
InputDir is input directory to search (includes all nested subdirectories).
|
||||
PathRegex is a regex to filter file paths.
|
||||
WriteToFileQ, when true, write to file, else, print a report of changes only.
|
||||
FixedCaseSearchQ sets `case-fold-search' for this operation.
|
||||
FixedCaseReplaceQ if true, then the letter-case in replacement is literal. (this is relevant only if FixedCaseSearchQ is true.)
|
||||
ShowcontexQ print characters before and after match.
|
||||
BackupQ if ture does backup.
|
||||
|
||||
Result is shown in buffer *xah-find output*.
|
||||
\\{xah-find-output-mode-map}
|
||||
|
||||
Version 2018-08-20 2021-10-11"
|
||||
(interactive
|
||||
(list
|
||||
(read-regexp "Find regex: " )
|
||||
(read-string (format "Replace string: ") nil 'query-replace-history)
|
||||
(ido-read-directory-name "Directory: " default-directory default-directory "MUSTMATCH")
|
||||
(read-from-minibuffer "File path regex: " (xah-find--get-fpath-regex "el") nil nil 'dired-regexp-history)
|
||||
(y-or-n-p "Write changes to file?")
|
||||
(y-or-n-p "Fixed case in search?")
|
||||
(y-or-n-p "Fixed case in replacement?")
|
||||
(y-or-n-p "Show context before after in output?")
|
||||
(y-or-n-p "Make backup?")))
|
||||
(let (($outBufName "*xah-find output*")
|
||||
$outBuffer
|
||||
($backupSuffix (xah-find--backup-suffix "xfr")))
|
||||
(when (get-buffer $outBufName) (kill-buffer $outBufName))
|
||||
(setq $outBuffer (generate-new-buffer $outBufName))
|
||||
(xah-find--print-header $outBuffer "xah-find-replace-text-regex" InputDir PathRegex Regex ReplaceStr WriteToFileQ BackupQ )
|
||||
(mapc
|
||||
(lambda ($fp)
|
||||
(let (($count 0))
|
||||
(with-temp-buffer
|
||||
(insert-file-contents $fp)
|
||||
(setq case-fold-search (not FixedCaseSearchQ))
|
||||
(while (re-search-forward Regex nil t)
|
||||
(setq $count (1+ $count))
|
||||
;; (xah-find--print-occur-block (match-beginning 0) (match-end 0) $outBuffer)
|
||||
(xah-find--occur-output (match-beginning 0) (match-end 0) $fp $outBuffer t)
|
||||
(replace-match ReplaceStr FixedCaseReplaceQ)
|
||||
(xah-find--occur-output (match-beginning 0) (point) $fp $outBuffer (not ShowcontexQ) t))
|
||||
(when (> $count 0)
|
||||
(xah-find--print-file-count $fp $count $outBuffer)
|
||||
(when WriteToFileQ
|
||||
(when BackupQ
|
||||
(copy-file $fp (concat $fp $backupSuffix) t))
|
||||
(write-region (point-min) (point-max) $fp nil 3))))))
|
||||
(seq-filter (lambda (x) (not (xah-find--ignore-dir-p x)))
|
||||
(directory-files-recursively InputDir PathRegex)))
|
||||
(princ "Done." $outBuffer)
|
||||
(xah-find--switch-to-output $outBuffer)))
|
||||
|
||||
(provide 'xah-find)
|
||||
|
||||
;;; xah-find.el ends here
|
||||
BIN
.emacs.d/xahemacs_2021-10-17.zip
Executable file
BIN
.emacs.d/xahemacs_2021-10-17.zip
Executable file
Binary file not shown.
Reference in New Issue
Block a user