Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

2211 linhas
72 KiB

  1. ;;; emacs.el --- 10sr emacs initialization
  2. ;;; Code:
  3. ;; SETUP_LOAD: (let ((file "DOTFILES_DIR/emacs.el"))
  4. ;; SETUP_LOAD: (and (file-readable-p file)
  5. ;; SETUP_LOAD: (byte-recompile-file file nil 0 t)))
  6. (setq debug-on-error t)
  7. ;; make directories
  8. (unless (file-directory-p (expand-file-name user-emacs-directory))
  9. (make-directory (expand-file-name user-emacs-directory)))
  10. (require 'cl-lib)
  11. (require 'simple)
  12. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  13. ;; Some macros for internals
  14. (defun call-after-init (func)
  15. "If `after-init-hook' has been run, call FUNC immediately.
  16. Otherwize hook it."
  17. (if after-init-time
  18. (funcall func)
  19. (add-hook 'after-init-hook
  20. func)))
  21. (defmacro safe-require-or-eval (feature)
  22. "Require FEATURE if available.
  23. At compile time the feature will be loaded immediately."
  24. `(eval-and-compile
  25. (message "safe-require-or-eval: Trying to require %s" ,feature)
  26. (require ,feature nil t)))
  27. (defmacro autoload-eval-lazily (feature &optional functions &rest body)
  28. "Define autoloading FEATURE that defines FUNCTIONS.
  29. FEATURE is a symbol. FUNCTIONS is a list of symbols. If FUNCTIONS is nil,
  30. the function same as FEATURE is defined as autoloaded function. BODY is passed
  31. to `eval-after-load'.
  32. After this macro is expanded, this returns the path to library if FEATURE
  33. found, otherwise returns nil."
  34. (declare (indent 2) (debug t))
  35. (let* ((libname (symbol-name (eval feature)))
  36. (libpath (locate-library libname)))
  37. `(progn
  38. (when (locate-library ,libname)
  39. ,@(mapcar (lambda (f)
  40. `(unless (fboundp ',f)
  41. (progn
  42. (message "Autoloaded function `%S' defined (%s)"
  43. (quote ,f)
  44. ,libpath)
  45. (autoload (quote ,f)
  46. ,libname
  47. ,(concat "Autoloaded function defined in \""
  48. libpath
  49. "\".")
  50. t))))
  51. (or (eval functions)
  52. `(,(eval feature)))))
  53. (eval-after-load ,feature
  54. (quote (progn
  55. ,@body)))
  56. (locate-library ,libname))))
  57. (when (autoload-eval-lazily 'tetris nil
  58. (message "Tetris loaded!"))
  59. (message "Tetris found!"))
  60. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  61. ;; package
  62. (set (defvar 10sr-package-list)
  63. '(
  64. vimrc-mode
  65. markdown-mode
  66. yaml-mode
  67. gnuplot-mode
  68. php-mode
  69. erlang
  70. js2-mode
  71. js-doc
  72. git-commit
  73. gitignore-mode
  74. adoc-mode
  75. go-mode
  76. ;; It seems malabar has been merged into jdee and this package
  77. ;; already removed
  78. ;; malabar-mode
  79. gosh-mode
  80. scala-mode
  81. ;;ensime
  82. ;; ack
  83. color-moccur
  84. ggtags
  85. flycheck
  86. auto-highlight-symbol
  87. hl-todo
  88. ;; Currently not available
  89. ;; pp-c-l
  90. xclip
  91. foreign-regexp
  92. multi-term
  93. term-run
  94. editorconfig
  95. git-ps1-mode
  96. restart-emacs
  97. fill-column-indicator
  98. pkgbuild-mode
  99. minibuffer-line
  100. which-key
  101. ;; I think this works in place of my autosave lib
  102. super-save
  103. pipenv
  104. imenu-list
  105. page-break-lines
  106. ;; sync-recentf
  107. aggressive-indent
  108. ;; fancy-narrow
  109. dired-filter
  110. wgrep
  111. magit
  112. git-gutter
  113. end-mark
  114. sl
  115. ;; TODO: Configure pony-tpl-mode
  116. pony-mode
  117. editorconfig
  118. editorconfig-custom-majormode
  119. git-command
  120. prompt-text
  121. ;; 10sr repository
  122. ;; 10sr-extras
  123. terminal-title
  124. recentf-show
  125. dired-list-all-mode
  126. pack
  127. set-modeline-color
  128. read-only-only-mode
  129. smart-revert
  130. autosave
  131. ;;window-organizer
  132. ilookup
  133. pasteboard
  134. awk-preview
  135. ))
  136. (when (safe-require-or-eval 'package)
  137. (setq package-archives
  138. `(,@package-archives
  139. ("melpa" . "https://melpa.org/packages/")
  140. ;; Somehow fails to download via https
  141. ("10sr-el" . "http://10sr.github.io/emacs-lisp/elpa/")))
  142. (package-initialize)
  143. (defun my-auto-install-package ()
  144. "Install packages semi-automatically."
  145. (interactive)
  146. (package-refresh-contents)
  147. (mapc (lambda (pkg)
  148. (or (package-installed-p pkg)
  149. (package-install pkg)))
  150. 10sr-package-list))
  151. )
  152. ;; (lazy-load-eval 'sudoku)
  153. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  154. ;; my-idle-hook
  155. (defvar my-idle-hook nil
  156. "Hook run when idle for several secs.")
  157. (defvar my-idle-hook-sec 5
  158. "Second to run `my-idle-hook'.")
  159. (run-with-idle-timer my-idle-hook-sec
  160. t
  161. (lambda ()
  162. (run-hooks 'my-idle-hook)))
  163. ;; (add-hook 'my-idle-hook
  164. ;; (lambda ()
  165. ;; (message "idle hook message")))
  166. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  167. ;; start and quit
  168. (setq inhibit-startup-message t)
  169. (setq confirm-kill-emacs 'y-or-n-p)
  170. (setq gc-cons-threshold (* 1024 1024 16))
  171. (setq garbage-collection-messages nil)
  172. (when window-system
  173. (add-to-list 'default-frame-alist '(cursor-type . box))
  174. (add-to-list 'default-frame-alist '(background-color . "white"))
  175. (add-to-list 'default-frame-alist '(foreground-color . "gray10"))
  176. ;; (add-to-list 'default-frame-alist '(alpha . (80 100 100 100)))
  177. ;; does not work?
  178. )
  179. ;; (add-to-list 'default-frame-alist '(cursor-type . box))
  180. (if window-system (menu-bar-mode 1) (menu-bar-mode 0))
  181. (and (fboundp 'tool-bar-mode)
  182. (tool-bar-mode 0))
  183. (and (fboundp 'set-scroll-bar-mode)
  184. (set-scroll-bar-mode nil))
  185. (call-after-init
  186. (lambda ()
  187. (message "%s %s" invocation-name emacs-version)
  188. (message "Invocation directory: %s" default-directory)
  189. (message "%s was taken to initialize emacs." (emacs-init-time))
  190. (view-echo-area-messages)
  191. ;; (view-emacs-news)
  192. ))
  193. (cd ".") ; when using windows use / instead of \ in `default-directory'
  194. ;; locale
  195. (set-language-environment "Japanese")
  196. (set-default-coding-systems 'utf-8-unix)
  197. (prefer-coding-system 'utf-8-unix)
  198. (setq system-time-locale "C")
  199. ;; my prefix map
  200. (defvar my-prefix-map nil
  201. "My prefix map.")
  202. (define-prefix-command 'my-prefix-map)
  203. ;; (define-key ctl-x-map (kbd "C-x") 'my-prefix-map)
  204. ;; (define-key my-prefix-map (kbd "C-q") 'quoted-insert)
  205. ;; (define-key my-prefix-map (kbd "C-z") 'suspend-frame)
  206. ;; (comint-show-maximum-output)
  207. ;; kill scratch
  208. (call-after-init (lambda ()
  209. (let ((buf (get-buffer "*scratch*")))
  210. (when buf
  211. (kill-buffer buf)))))
  212. ;; modifier keys
  213. ;; (setq mac-option-modifier 'control)
  214. ;; display
  215. (setq visible-bell t)
  216. (setq ring-bell-function 'ignore)
  217. (mouse-avoidance-mode 'banish)
  218. (setq echo-keystrokes 0.1)
  219. (defun reload-init-file ()
  220. "Reload Emacs init file."
  221. (interactive)
  222. (when (and user-init-file
  223. (file-readable-p user-init-file))
  224. (load-file user-init-file)))
  225. (safe-require-or-eval 'session)
  226. ;; server
  227. (set-variable 'server-name (concat "server"
  228. (number-to-string (emacs-pid))))
  229. ;; In Cygwin Environment `server-runnning-p' stops when server-use-tcp is nil
  230. ;; In Darwin environment, init fails with message like 'Service name too long'
  231. ;; when server-use-tcp is nil
  232. (when (or (eq system-type
  233. 'cygwin)
  234. (eq system-type
  235. 'darwin))
  236. (set-variable 'server-use-tcp t))
  237. ;; MSYS2 fix
  238. (when (eq system-type
  239. 'windows-nt)
  240. (setq shell-file-name
  241. (executable-find "bash"))
  242. '(setq function-key-map
  243. `(,@function-key-map ([pause] . [?\C-c])
  244. ))
  245. (define-key key-translation-map
  246. (kbd "<pause>")
  247. (kbd "C-c"))
  248. '(keyboard-translate [pause]
  249. (kbd "C-c")p)
  250. ;; TODO: move to other place later
  251. (when (not window-system)
  252. (setq interprogram-paste-function nil)
  253. (setq interprogram-cut-function nil)))
  254. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  255. ;; global keys
  256. (global-set-key (kbd "<up>") 'scroll-down-line)
  257. (global-set-key (kbd "<down>") 'scroll-up-line)
  258. (global-set-key (kbd "<left>") 'scroll-down)
  259. (global-set-key (kbd "<right>") 'scroll-up)
  260. ;; (define-key my-prefix-map (kbd "C-h") help-map)
  261. (global-set-key (kbd "C-\\") help-map)
  262. (define-key ctl-x-map (kbd "DEL") help-map)
  263. (define-key ctl-x-map (kbd "C-h") help-map)
  264. (define-key help-map "a" 'apropos)
  265. ;; disable annoying keys
  266. (global-set-key [prior] 'ignore)
  267. (global-set-key (kbd "<next>") 'ignore)
  268. (global-set-key [menu] 'ignore)
  269. (global-set-key [down-mouse-1] 'ignore)
  270. (global-set-key [down-mouse-2] 'ignore)
  271. (global-set-key [down-mouse-3] 'ignore)
  272. (global-set-key [mouse-1] 'ignore)
  273. (global-set-key [mouse-2] 'ignore)
  274. (global-set-key [mouse-3] 'ignore)
  275. (global-set-key (kbd "<eisu-toggle>") 'ignore)
  276. (global-set-key (kbd "C-<eisu-toggle>") 'ignore)
  277. (when (safe-require-or-eval 'which-key)
  278. (which-key-mode))
  279. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  280. ;; editor
  281. (setq kill-whole-line t)
  282. (setq scroll-conservatively 35
  283. scroll-margin 2)
  284. (setq-default major-mode 'text-mode)
  285. (setq next-line-add-newlines nil)
  286. (setq kill-read-only-ok t)
  287. (setq truncate-partial-width-windows nil) ; when splitted horizontally
  288. ;; (setq-default line-spacing 0.2)
  289. (setq-default indicate-empty-lines t) ; when using x indicate empty line
  290. ;; (setq-default tab-width 4)
  291. (setq-default indent-tabs-mode nil)
  292. (setq-default indent-line-function 'indent-to-left-margin)
  293. ;; (setq-default indent-line-function nil)
  294. (setq-default truncate-lines nil)
  295. ;; (pc-selection-mode 1) ; make some already defined keybind back to default
  296. (delete-selection-mode 1)
  297. (cua-mode 0)
  298. (setq line-move-visual nil)
  299. (setq create-lockfiles nil)
  300. (add-hook 'before-save-hook
  301. 'time-stamp)
  302. ;; Add Time-stamp: <> to insert timestamp there
  303. (set-variable 'time-stamp-format
  304. "%:y-%02m-%02d %02H:%02M:%02S %Z 10sr")
  305. ;; key bindings
  306. ;; moving around
  307. ;;(keyboard-translate ?\M-j ?\C-j)
  308. ;; (global-set-key (kbd "M-p") 'backward-paragraph)
  309. (define-key esc-map "p" 'backward-paragraph)
  310. ;; (global-set-key (kbd "M-n") 'forward-paragraph)
  311. (define-key esc-map "n" 'forward-paragraph)
  312. (global-set-key (kbd "C-<up>") 'scroll-down-line)
  313. (global-set-key (kbd "C-<down>") 'scroll-up-line)
  314. (global-set-key (kbd "C-<left>") 'scroll-down)
  315. (global-set-key (kbd "C-<right>") 'scroll-up)
  316. (global-set-key (kbd "<select>") 'ignore) ; 'previous-line-mark)
  317. (define-key ctl-x-map (kbd "ESC x") 'execute-extended-command)
  318. (define-key ctl-x-map (kbd "ESC :") 'eval-expression)
  319. ;; C-h and DEL
  320. (global-set-key (kbd "C-h") (kbd "DEL"))
  321. ;;(global-set-key (kbd "C-m") 'reindent-then-newline-and-indent)
  322. (global-set-key (kbd "C-m") 'newline-and-indent)
  323. ;; (global-set-key (kbd "C-o") (kbd "C-e C-m"))
  324. ;; (global-set-key "\C-z" 'undo) ; undo is M-u
  325. (define-key esc-map "u" 'undo)
  326. (define-key esc-map "i" (kbd "ESC TAB"))
  327. ;; (global-set-key (kbd "C-r") 'query-replace-regexp)
  328. (global-set-key (kbd "C-s") 'isearch-forward-regexp)
  329. (global-set-key (kbd "C-r") 'isearch-backward-regexp)
  330. (require 'page-ext nil t)
  331. (when (safe-require-or-eval 'page-break-lines)
  332. (global-page-break-lines-mode 1))
  333. (when (safe-require-or-eval 'git-gutter)
  334. (custom-set-variables
  335. '(git-gutter:lighter " Gttr"))
  336. (custom-set-variables
  337. '(git-gutter:update-interval 2))
  338. (custom-set-variables
  339. '(git-gutter:unchanged-sign " "))
  340. (when (= (display-color-cells)
  341. 256)
  342. (let ((c "color-233"))
  343. (set-face-background 'git-gutter:modified c)
  344. (set-face-background 'git-gutter:added c)
  345. (set-face-background 'git-gutter:deleted c)
  346. (set-face-background 'git-gutter:unchanged c)))
  347. (global-git-gutter-mode 1)
  348. )
  349. ;; (when (safe-require-or-eval 'fancy-narrow)
  350. ;; (fancy-narrow-mode 1))
  351. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  352. ;; title and mode-line
  353. (when (safe-require-or-eval 'terminal-title)
  354. ;; if TERM is not screen use default value
  355. (if (getenv "TMUX")
  356. ;; if use tmux locally just basename of current dir
  357. (set-variable 'terminal-title-format
  358. '((file-name-nondirectory (directory-file-name
  359. default-directory))))
  360. (if (and (let ((tty-type (frame-parameter nil
  361. 'tty-type)))
  362. (and tty-type
  363. (equal (car (split-string tty-type
  364. "-"))
  365. "screen")))
  366. (not (getenv "SSH_CONNECTION")))
  367. (set-variable 'terminal-title-format
  368. '((file-name-nondirectory (directory-file-name
  369. default-directory))))
  370. ;; seems that TMUX is used locally and ssh to remote host
  371. (set-variable 'terminal-title-format
  372. `("em:"
  373. ,user-login-name
  374. "@"
  375. ,(car (split-string (system-name)
  376. "\\."))
  377. ":"
  378. default-directory))
  379. )
  380. )
  381. (terminal-title-mode))
  382. (setq eol-mnemonic-dos "\\r\\n")
  383. (setq eol-mnemonic-mac "\\r")
  384. (setq eol-mnemonic-unix "")
  385. (which-function-mode 1)
  386. (line-number-mode 0)
  387. (column-number-mode 0)
  388. (size-indication-mode 0)
  389. (setq mode-line-position
  390. '(:eval (format "L%%l/%d%s:C%%c"
  391. (count-lines (point-max)
  392. (point-min))
  393. (if (buffer-narrowed-p)
  394. "[N]"
  395. "")
  396. )))
  397. ;; http://www.geocities.jp/simizu_daisuke/bunkei-meadow.html#frame-title
  398. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  399. ;; minibuffer
  400. (setq insert-default-directory t)
  401. (setq completion-ignore-case t
  402. read-file-name-completion-ignore-case t
  403. read-buffer-completion-ignore-case t)
  404. (setq resize-mini-windows t)
  405. (temp-buffer-resize-mode 1)
  406. (savehist-mode 1)
  407. (defvar display-time-format "%Y/%m/%d %a %H:%M")
  408. (set-variable 'help-at-pt-display-when-idle t)
  409. (fset 'yes-or-no-p 'y-or-n-p)
  410. ;; complete symbol when `eval'
  411. (define-key read-expression-map (kbd "TAB") 'completion-at-point)
  412. (define-key minibuffer-local-map (kbd "C-u")
  413. (lambda () (interactive) (delete-region (point-at-bol) (point))))
  414. ;; I dont know these bindings are good
  415. (define-key minibuffer-local-map (kbd "C-p") (kbd "ESC p"))
  416. (define-key minibuffer-local-map (kbd "C-n") (kbd "ESC n"))
  417. (when (safe-require-or-eval 'minibuffer-line)
  418. (set-face-underline 'minibuffer-line nil)
  419. (set-variable 'minibuffer-line-refresh-interval
  420. 25)
  421. ;; Set idle timer
  422. (defvar my-minibuffer-line--idle-timer nil)
  423. (defvar minibuffer-line-mode)
  424. (add-hook 'minibuffer-line-mode-hook
  425. (lambda ()
  426. (when my-minibuffer-line--idle-timer
  427. (cancel-timer my-minibuffer-line--idle-timer)
  428. (setq my-minibuffer-line--idle-timer nil))
  429. (when minibuffer-line-mode
  430. (setq my-minibuffer-line--idle-timer
  431. (run-with-idle-timer 0.5
  432. t
  433. 'minibuffer-line--update)))))
  434. (set-variable 'minibuffer-line-format
  435. `(,(concat user-login-name
  436. "@"
  437. (car (split-string (system-name)
  438. "\\."))
  439. ":")
  440. (:eval (abbreviate-file-name (or buffer-file-name
  441. default-directory)))
  442. (:eval (and (fboundp 'git-ps1-mode-get-current)
  443. (git-ps1-mode-get-current " [GIT:%s]")))
  444. " "
  445. (:eval (format-time-string display-time-format))))
  446. (minibuffer-line-mode 1)
  447. )
  448. (when (safe-require-or-eval 'prompt-text)
  449. (set-variable 'prompt-text-format
  450. `(,(concat ""
  451. user-login-name
  452. "@"
  453. (car (split-string (system-name)
  454. "\\."))
  455. ":")
  456. (:eval (abbreviate-file-name (or buffer-file-name
  457. default-directory)))
  458. (:eval (and (fboundp 'git-ps1-mode-get-current)
  459. (git-ps1-mode-get-current " [GIT:%s]")))
  460. " "
  461. (:eval (format-time-string display-time-format))
  462. "\n"
  463. (:eval (symbol-name this-command))
  464. ": "))
  465. (prompt-text-mode 1))
  466. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  467. ;; letters, font-lock mode and fonts
  468. (setq text-quoting-style 'grave)
  469. ;; (set-face-background 'vertical-border (face-foreground 'mode-line))
  470. ;; (set-window-margins (selected-window) 1 1)
  471. (unless window-system
  472. (setq frame-background-mode 'dark))
  473. (and (or (eq system-type 'Darwin)
  474. (eq system-type 'darwin))
  475. (fboundp 'mac-set-input-method-parameter)
  476. (mac-set-input-method-parameter 'japanese 'cursor-color "red")
  477. (mac-set-input-method-parameter 'roman 'cursor-color "black"))
  478. (when (and (boundp 'input-method-activate-hook) ; i dont know this is correct
  479. (boundp 'input-method-inactivate-hook))
  480. (add-hook 'input-method-activate-hook
  481. (lambda () (set-cursor-color "red")))
  482. (add-hook 'input-method-inactivate-hook
  483. (lambda () (set-cursor-color "black"))))
  484. (when (safe-require-or-eval 'paren)
  485. (show-paren-mode 1)
  486. (setq show-paren-delay 0.5
  487. show-paren-style 'parenthesis) ; mixed is hard to read
  488. ;; (set-face-background 'show-paren-match
  489. ;; "black")
  490. ;; ;; (face-foreground 'default))
  491. ;; (set-face-foreground 'show-paren-match
  492. ;; "white")
  493. ;; (set-face-inverse-video-p 'show-paren-match
  494. ;; t)
  495. )
  496. (transient-mark-mode 1)
  497. (global-font-lock-mode 1)
  498. (setq font-lock-global-modes
  499. '(not
  500. help-mode
  501. eshell-mode
  502. ;;term-mode
  503. Man-mode
  504. magit-diff-mode
  505. magit-revision-mode))
  506. ;; (standard-display-ascii ?\n "$\n")
  507. ;; (defvar my-eol-face
  508. ;; '(("\n" . (0 font-lock-comment-face t nil)))
  509. ;; )
  510. ;; (defvar my-tab-face
  511. ;; '(("\t" . '(0 highlight t nil))))
  512. (defvar my-jspace-face
  513. '(("\u3000" . '(0 highlight t nil))))
  514. (add-hook 'font-lock-mode-hook
  515. (lambda ()
  516. ;; (font-lock-add-keywords nil my-eol-face)
  517. (font-lock-add-keywords nil my-jspace-face)
  518. ))
  519. (when (safe-require-or-eval 'whitespace)
  520. (add-to-list 'whitespace-display-mappings
  521. ;; We need t since last one takes precedence
  522. `(tab-mark ?\t ,(vconcat "^I\t")) t)
  523. ;; (add-to-list 'whitespace-display-mappings
  524. ;; `(newline-mark ?\n ,(vconcat "$\n")))
  525. (setq whitespace-style '(face
  526. trailing ; trailing blanks
  527. ;; tabs
  528. ;; spaces
  529. ;; lines
  530. lines-tail ; lines over 80
  531. newline ; newlines
  532. empty ; empty lines at beg or end of buffer
  533. ;; big-indent
  534. ;; space-mark
  535. tab-mark
  536. newline-mark ; use display table for newline
  537. ))
  538. ;; (setq whitespace-newline 'font-lock-comment-face)
  539. ;; (setq whitespace-style (delq 'newline-mark whitespace-style))
  540. (defun my-whitesspace-mode-reload ()
  541. "Reload whitespace-mode config."
  542. (interactive)
  543. (when whitespace-mode
  544. (whitespace-mode 0)
  545. (whitespace-mode 1)))
  546. (set-variable 'whitespace-line-column nil)
  547. (global-whitespace-mode t)
  548. (add-hook 'dired-mode-hook
  549. (lambda ()
  550. (set (make-local-variable 'whitespace-style) nil)))
  551. (if (= (display-color-cells)
  552. 256)
  553. (set-face-foreground 'whitespace-newline "color-109")
  554. ;; (progn
  555. ;; (set-face-bold-p 'whitespace-newline
  556. ;; t))
  557. ))
  558. (and nil
  559. '(safe-require-or-eval 'fill-column-indicator)
  560. (setq fill-column-indicator))
  561. ;; highlight current line
  562. ;; http://wiki.riywo.com/index.php?Meadow
  563. (face-spec-set 'hl-line
  564. '((((min-colors 256)
  565. (background dark))
  566. (:background "color-234"))
  567. (((min-colors 256)
  568. (background light))
  569. (:background "color-234"))
  570. (t
  571. (:underline "black"))))
  572. (set-variable 'hl-line-global-modes
  573. '(not
  574. term-mode))
  575. (global-hl-line-mode 1) ;; (hl-line-mode 1)
  576. (set-face-foreground 'font-lock-regexp-grouping-backslash "#666")
  577. (set-face-foreground 'font-lock-regexp-grouping-construct "#f60")
  578. ;;(safe-require-or-eval 'set-modeline-color)
  579. ;; (let ((fg (face-foreground 'default))
  580. ;; (bg (face-background 'default)))
  581. ;; (set-face-background 'mode-line-inactive
  582. ;; (if (face-inverse-video-p 'mode-line) fg bg))
  583. ;; (set-face-foreground 'mode-line-inactive
  584. ;; (if (face-inverse-video-p 'mode-line) bg fg)))
  585. ;; (set-face-underline 'mode-line-inactive
  586. ;; t)
  587. ;; (set-face-underline 'vertical-border
  588. ;; nil)
  589. ;; (when (safe-require-or-eval 'end-mark)
  590. ;; (global-end-mark-mode))
  591. ;; M-x highlight-* to highlight things
  592. (global-hi-lock-mode 1)
  593. (unless (fboundp 'highlight-region-text)
  594. (defun highlight-region-text (beg end)
  595. "Highlight text between BEG and END."
  596. (interactive "r")
  597. (highlight-regexp (regexp-quote (buffer-substring-no-properties beg
  598. end)))
  599. (setq deactivate-mark t)))
  600. (when (safe-require-or-eval 'auto-highlight-symbol)
  601. (set-variable 'ahs-idle-interval 0.6)
  602. (global-auto-highlight-symbol-mode 1))
  603. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  604. ;; file handling
  605. (when (safe-require-or-eval 'editorconfig)
  606. ;; (set-variable 'editorconfig-get-properties-function
  607. ;; 'editorconfig-core-get-properties-hash)
  608. (editorconfig-mode 1)
  609. (set-variable 'editorconfig-mode-lighter " EC")
  610. (with-eval-after-load 'org-src
  611. ;; [*.org\[\*Org Src*\[ c \]*\]]
  612. (add-hook 'org-src-mode-hook
  613. 'editorconfig-mode-apply t)))
  614. (when (fboundp 'editorconfig-custom-majormode)
  615. (add-hook 'editorconfig-after-apply-functions
  616. 'editorconfig-custom-majormode))
  617. ;; Add readonly=true to set read-only-mode
  618. (add-hook 'editorconfig-after-apply-functions
  619. (lambda (props)
  620. (let ((r (gethash 'readonly props)))
  621. (when (and (string= r "true")
  622. (not buffer-read-only))
  623. (read-only-mode 1)))))
  624. (add-hook 'editorconfig-hack-properties-functions
  625. '(lambda (props)
  626. (when (derived-mode-p 'makefile-mode)
  627. (puthash 'indent_style "tab" props))))
  628. ;; (when (fboundp 'editorconfig-charset-extras)
  629. ;; (add-hook 'editorconfig-custom-hooks
  630. ;; 'editorconfig-charset-extras))
  631. (setq revert-without-query '(".+"))
  632. ;; save cursor position
  633. (when (safe-require-or-eval 'saveplace)
  634. (setq-default save-place t)
  635. (setq save-place-file (concat user-emacs-directory
  636. "places")))
  637. ;; http://www.bookshelf.jp/soft/meadow_24.html#SEC260
  638. (setq make-backup-files t)
  639. (setq vc-make-backup-files t)
  640. ;; (make-directory (expand-file-name "~/.emacsbackup"))
  641. (setq backup-directory-alist
  642. (cons (cons "." (expand-file-name (concat user-emacs-directory
  643. "backup")))
  644. backup-directory-alist))
  645. (setq version-control 't)
  646. (setq delete-old-versions t)
  647. (setq kept-new-versions 20)
  648. (setq auto-save-list-file-prefix (expand-file-name (concat user-emacs-directory
  649. "auto-save/")))
  650. ;; (setq delete-auto-save-files t)
  651. (setq auto-save-visited-interval 8)
  652. (auto-save-visited-mode 1)
  653. (add-to-list 'completion-ignored-extensions ".bak")
  654. (set-variable 'completion-cycle-threshold nil) ;; NEVER use
  655. (setq delete-by-moving-to-trash t)
  656. ;; trash-directory "~/.emacs.d/trash")
  657. (add-hook 'after-save-hook
  658. 'executable-make-buffer-file-executable-if-script-p)
  659. (set-variable 'bookmark-default-file
  660. (expand-file-name (concat user-emacs-directory
  661. "bmk")))
  662. (set-variable 'bookmark-save-flag
  663. 1)
  664. (with-eval-after-load 'recentf
  665. (defvar recentf-exclude)
  666. (defvar bookmark-default-file)
  667. (add-to-list 'recentf-exclude
  668. (regexp-quote bookmark-default-file)))
  669. (when (safe-require-or-eval 'smart-revert)
  670. (smart-revert-on))
  671. ;; autosave
  672. ;; auto-save-visited-mode can be used instead?
  673. ;; (when (safe-require-or-eval 'autosave)
  674. ;; (autosave-set 8))
  675. ;; bookmarks
  676. (define-key ctl-x-map "m" 'list-bookmarks)
  677. ;; vc
  678. (set-variable 'vc-handled-backends '(RCS))
  679. (set-variable 'vc-rcs-register-switches "-l")
  680. (set-variable 'vc-rcs-checkin-switches "-l")
  681. (set-variable 'vc-command-messages t)
  682. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  683. ;; share clipboard with x
  684. ;; this page describes this in details, but only these sexps seem to be needed
  685. ;; http://garin.jp/doc/Linux/xwindow_clipboard
  686. (and nil
  687. (not window-system)
  688. (not (eq window-system 'mac))
  689. (getenv "DISPLAY")
  690. (not (equal (getenv "DISPLAY") ""))
  691. (executable-find "xclip")
  692. ;; (< emacs-major-version 24)
  693. '(safe-require-or-eval 'xclip)
  694. nil
  695. (turn-on-xclip))
  696. (and (eq system-type 'darwin)
  697. (safe-require-or-eval 'pasteboard)
  698. (turn-on-pasteboard))
  699. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  700. ;; some modes and hooks
  701. ;; Include some extra modes
  702. (require 'generic-x)
  703. (when (autoload-eval-lazily 'wgrep)
  704. (set-variable 'wgrep-auto-save-buffer t)
  705. (with-eval-after-load 'grep
  706. (defvar grep-mode-map)
  707. (define-key grep-mode-map
  708. "e"
  709. 'wgrep-change-to-wgrep-mode)))
  710. (with-eval-after-load 'remember
  711. (defvar remember-mode-map (make-sparse-keymap))
  712. (define-key remember-mode-map (kbd "C-x C-s") 'ignore))
  713. (with-eval-after-load 'magit-files
  714. ;; `global-magit-file-mode' is enabled by default and this mode overwrites
  715. ;; existing keybindings.
  716. ;; Apparently it is a HARMFUL behavior and it is really awful that I have
  717. ;; to disable thie mode here, but do anyway.
  718. ;; See also https://github.com/magit/magit/issues/3517
  719. (global-magit-file-mode -1))
  720. (with-eval-after-load 'magit-section
  721. (set-face-background 'magit-section-highlight
  722. nil))
  723. (with-eval-after-load 'magit-diff
  724. (set-face-background 'magit-diff-added-highlight
  725. nil)
  726. (set-face-background 'magit-diff-removed-highlight
  727. nil)
  728. (set-face-background 'magit-diff-context-highlight
  729. nil)
  730. )
  731. (when (boundp 'git-rebase-filename-regexp)
  732. (add-to-list 'auto-mode-alist
  733. `(,git-rebase-filename-regexp . text-mode)))
  734. (when (safe-require-or-eval 'aggressive-indent)
  735. (defvar aggressive-indent-excluded-modes)
  736. (setq aggressive-indent-excluded-modes
  737. `(diff-mode
  738. toml-mode
  739. conf-mode
  740. dockerfile-mode
  741. groovy-mode
  742. ,@aggressive-indent-excluded-modes))
  743. (global-aggressive-indent-mode 1))
  744. (when (autoload-eval-lazily 'ggtags)
  745. (add-hook 'c-mode-common-hook
  746. (lambda ()
  747. (when (derived-mode-p 'c-mode 'c++-mode 'java-mode)
  748. (ggtags-mode 1))))
  749. (add-hook 'python-mode-hook
  750. (lambda ()
  751. (ggtags-mode 1))))
  752. (when (autoload-eval-lazily 'imenu-list)
  753. ;; (set-variable 'imenu-list-auto-resize t)
  754. (set-variable 'imenu-list-focus-after-activation t)
  755. (define-key ctl-x-map "l" 'imenu-list-smart-toggle))
  756. (add-hook 'emacs-lisp-mode-hook
  757. (lambda ()
  758. (setq imenu-generic-expression
  759. `(("Sections" ";;;\+\n;; \\(.*\\)\n" 1)
  760. ,@imenu-generic-expression))))
  761. (with-eval-after-load 'compile
  762. (defvar compilation-filter-start)
  763. (defvar compilation-error-regexp-alist)
  764. (require 'ansi-color)
  765. (add-hook 'compilation-filter-hook
  766. (lambda ()
  767. (let ((inhibit-read-only t))
  768. (ansi-color-apply-on-region compilation-filter-start
  769. (point)))))
  770. (add-to-list 'compilation-error-regexp-alist
  771. ;; ansible-lint
  772. '("^\\([^ \n]+\\):\\([0-9]+\\)$" 1 2)))
  773. ;; Workaround to avoid ensime error
  774. (defvar ensime-mode-key-prefix nil)
  775. ;; http://qiita.com/sune2/items/b73037f9e85962f5afb7
  776. (when (safe-require-or-eval 'company)
  777. (global-company-mode)
  778. (set-variable 'company-idle-delay 0.5)
  779. (set-variable 'company-minimum-prefix-length 2)
  780. (set-variable 'company-selection-wrap-around t))
  781. ;; https://github.com/lunaryorn/flycheck
  782. (when (safe-require-or-eval 'flycheck)
  783. (call-after-init 'global-flycheck-mode))
  784. (when (autoload-eval-lazily 'ilookup)
  785. (define-key ctl-x-map "d" 'ilookup-open-word))
  786. (set-variable 'ac-ignore-case nil)
  787. (when (autoload-eval-lazily 'term-run '(term-run-shell-command term-run))
  788. (define-key ctl-x-map "t" 'term-run-shell-command))
  789. (add-to-list 'safe-local-variable-values
  790. '(encoding utf-8))
  791. (setq enable-local-variables :safe)
  792. ;; Detect file type from shebang and set major-mode.
  793. (add-to-list 'interpreter-mode-alist
  794. '("python3" . python-mode))
  795. (add-to-list 'interpreter-mode-alist
  796. '("python2" . python-mode))
  797. (with-eval-after-load 'python
  798. (defvar python-mode-map (make-sparse-keymap))
  799. (define-key python-mode-map (kbd "C-m") 'newline-and-indent))
  800. (when (autoload-eval-lazily 'pipenv)
  801. (add-hook 'python-mode-hook
  802. (lambda ()
  803. (pipenv-mode 1)
  804. (pipenv-projectile-after-switch-default)))
  805. )
  806. (set-variable 'flycheck-python-pycompile-executable "python3")
  807. (set-variable 'python-indent-guess-indent-offset nil)
  808. ;; http://fukuyama.co/foreign-regexp
  809. '(and (safe-require-or-eval 'foreign-regexp)
  810. (progn
  811. (setq foreign-regexp/regexp-type 'perl)
  812. '(setq reb-re-syntax 'foreign-regexp)
  813. ))
  814. (autoload-eval-lazily 'sql '(sql-mode)
  815. (require 'sql-indent nil t))
  816. (when (autoload-eval-lazily 'git-command)
  817. (define-key ctl-x-map "g" 'git-command))
  818. (when (safe-require-or-eval 'git-commit)
  819. (global-git-commit-mode 1))
  820. (with-eval-after-load 'git-commit
  821. (add-hook 'git-commit-setup-hook
  822. 'turn-off-auto-fill t))
  823. (autoload-eval-lazily 'sl)
  824. (with-eval-after-load 'rst
  825. (defvar rst-mode-map)
  826. (define-key rst-mode-map (kbd "C-m") 'newline-and-indent))
  827. (with-eval-after-load 'jdee
  828. (add-hook 'jdee-mode-hook
  829. (lambda ()
  830. (make-local-variable 'global-mode-string)
  831. (add-to-list 'global-mode-string
  832. mode-line-position))))
  833. ;; Cannot enable error thrown. Why???
  834. ;; https://github.com/m0smith/malabar-mode#Installation
  835. ;; (when (autoload-eval-lazily 'malabar-mode)
  836. ;; (add-to-list 'load-path
  837. ;; (expand-file-name (concat user-emacs-directory "/cedet")))
  838. ;; (safe-require-or-eval 'cedet-devel-load)
  839. ;; (call-after-init 'activate-malabar-mode))
  840. (with-eval-after-load 'make-mode
  841. (defvar makefile-mode-map (make-sparse-keymap))
  842. (define-key makefile-mode-map (kbd "C-m") 'newline-and-indent)
  843. ;; this functions is set in write-file-functions, i cannot find any
  844. ;; good way to remove this.
  845. (fset 'makefile-warn-suspicious-lines 'ignore))
  846. (with-eval-after-load 'verilog-mode
  847. (defvar verilog-mode-map (make-sparse-keymap))
  848. (define-key verilog-mode-map ";" 'self-insert-command))
  849. (setq diff-switches "-u")
  850. (with-eval-after-load 'diff-mode
  851. ;; (when (and (eq major-mode
  852. ;; 'diff-mode)
  853. ;; (not buffer-file-name))
  854. ;; ;; do not pass when major-mode is derived mode of diff-mode
  855. ;; (view-mode 1))
  856. (set-face-attribute 'diff-header nil
  857. :foreground nil
  858. :background nil
  859. :weight 'bold)
  860. (set-face-attribute 'diff-file-header nil
  861. :foreground nil
  862. :background nil
  863. :weight 'bold)
  864. (set-face-foreground 'diff-index "blue")
  865. (set-face-attribute 'diff-hunk-header nil
  866. :foreground "cyan"
  867. :weight 'normal)
  868. (set-face-attribute 'diff-context nil
  869. ;; :foreground "white"
  870. :foreground nil
  871. :weight 'normal)
  872. (set-face-foreground 'diff-removed "red")
  873. (set-face-foreground 'diff-added "green")
  874. (set-face-background 'diff-removed nil)
  875. (set-face-background 'diff-added nil)
  876. (set-face-attribute 'diff-changed nil
  877. :foreground "magenta"
  878. :weight 'normal)
  879. (set-face-attribute 'diff-refine-changed nil
  880. :foreground nil
  881. :background nil
  882. :weight 'bold
  883. :inverse-video t)
  884. ;; Annoying !
  885. ;;(diff-auto-refine-mode)
  886. )
  887. ;; (ffap-bindings)
  888. (set-variable 'browse-url-browser-function
  889. 'eww-browse-url)
  890. (set-variable 'sh-here-document-word "__EOC__")
  891. (when (autoload-eval-lazily 'adoc-mode
  892. nil
  893. (defvar adoc-mode-map (make-sparse-keymap))
  894. (define-key adoc-mode-map (kbd "C-m") 'newline))
  895. (setq auto-mode-alist
  896. `(("\\.adoc\\'" . adoc-mode)
  897. ("\\.asciidoc\\'" . adoc-mode)
  898. ,@auto-mode-alist)))
  899. (with-eval-after-load 'markup-faces
  900. ;; Is this too match ?
  901. (set-face-foreground 'markup-meta-face
  902. "color-245")
  903. (set-face-foreground 'markup-meta-hide-face
  904. "color-245")
  905. )
  906. ;; TODO: check if this is required
  907. (when (autoload-eval-lazily 'groovy-mode nil
  908. (defvar groovy-mode-map (make-sparse-keymap))
  909. (define-key groovy-mode-map "(" 'self-insert-command)
  910. (define-key groovy-mode-map ")" 'self-insert-command)
  911. (define-key groovy-mode-map (kbd "C-m") 'newline-and-indent)
  912. )
  913. (add-to-list 'auto-mode-alist
  914. '("build\\.gradle\\'" . groovy-mode)))
  915. (with-eval-after-load 'yaml-mode
  916. (defvar yaml-mode-map (make-sparse-keymap))
  917. (define-key yaml-mode-map (kbd "C-m") 'newline))
  918. (with-eval-after-load 'html-mode
  919. (defvar html-mode-map (make-sparse-keymap))
  920. (define-key html-mode-map (kbd "C-m") 'reindent-then-newline-and-indent))
  921. (with-eval-after-load 'text-mode
  922. (define-key text-mode-map (kbd "C-m") 'newline))
  923. (autoload-eval-lazily 'info nil
  924. (defvar Info-additional-directory-list)
  925. (dolist (dir (directory-files (concat user-emacs-directory
  926. "info")
  927. t
  928. "^[^.].*"))
  929. (when (file-directory-p dir)
  930. (add-to-list 'Info-additional-directory-list
  931. dir)))
  932. (let ((dir (expand-file-name "~/.brew/share/info")))
  933. (when (file-directory-p dir)
  934. (add-to-list 'Info-additional-directory-list
  935. dir))))
  936. (with-eval-after-load 'apropos
  937. (defvar apropos-mode-map (make-sparse-keymap))
  938. (define-key apropos-mode-map "n" 'next-line)
  939. (define-key apropos-mode-map "p" 'previous-line))
  940. ;; `isearch' library does not call `provide' so cannot use with-eval-after-load
  941. ;; (define-key isearch-mode-map
  942. ;; (kbd "C-j") 'isearch-other-control-char)
  943. ;; (define-key isearch-mode-map
  944. ;; (kbd "C-k") 'isearch-other-control-char)
  945. ;; (define-key isearch-mode-map
  946. ;; (kbd "C-h") 'isearch-other-control-char)
  947. (define-key isearch-mode-map (kbd "C-h") 'isearch-del-char)
  948. (define-key isearch-mode-map (kbd "M-r")
  949. 'isearch-query-replace-regexp)
  950. ;; do not cleanup isearch highlight: use `lazy-highlight-cleanup' to remove
  951. (setq lazy-highlight-cleanup nil)
  952. ;; face for isearch highlighing
  953. (set-face-attribute 'lazy-highlight
  954. nil
  955. :foreground `unspecified
  956. :background `unspecified
  957. :underline t
  958. ;; :weight `bold
  959. )
  960. (add-hook 'outline-mode-hook
  961. (lambda ()
  962. (when (string-match "\\.md\\'" buffer-file-name)
  963. (set (make-local-variable 'outline-regexp) "#+ "))))
  964. (add-hook 'outline-mode-hook
  965. 'outline-show-all)
  966. (add-to-list 'auto-mode-alist (cons "\\.ol\\'" 'outline-mode))
  967. (add-to-list 'auto-mode-alist (cons "\\.md\\'" 'outline-mode))
  968. (when (autoload-eval-lazily 'markdown-mode
  969. '(markdown-mode gfm-mode)
  970. (defvar gfm-mode-map (make-sparse-keymap))
  971. (define-key gfm-mode-map (kbd "C-m") 'electric-indent-just-newline))
  972. (add-to-list 'auto-mode-alist (cons "\\.md\\'" 'gfm-mode))
  973. (set-variable 'markdown-command (or (executable-find "markdown")
  974. (executable-find "markdown.pl")
  975. ""))
  976. (add-hook 'markdown-mode-hook
  977. (lambda ()
  978. (outline-minor-mode 1)
  979. (flyspell-mode)
  980. (set (make-local-variable 'comment-start) ";")))
  981. )
  982. ;; c-mode
  983. ;; http://www.emacswiki.org/emacs/IndentingC
  984. ;; http://en.wikipedia.org/wiki/Indent_style
  985. ;; http://d.hatena.ne.jp/emergent/20070203/1170512717
  986. ;; http://seesaawiki.jp/whiteflare503/d/Emacs%20%a5%a4%a5%f3%a5%c7%a5%f3%a5%c8
  987. (with-eval-after-load 'cc-vars
  988. (defvar c-default-style nil)
  989. (add-to-list 'c-default-style
  990. '(c-mode . "k&r"))
  991. (add-to-list 'c-default-style
  992. '(c++-mode . "k&r")))
  993. (autoload-eval-lazily 'js2-mode nil
  994. ;; currently do not use js2-mode
  995. ;; (add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))
  996. ;; (add-to-list 'auto-mode-alist '("\\.jsm\\'" . js2-mode))
  997. ;; (defvar js2-mode-map (make-sparse-keymap))
  998. ;; (define-key js2-mode-map (kbd "C-m") (lambda ()
  999. ;; (interactive)
  1000. ;; (js2-enter-key)
  1001. ;; (indent-for-tab-command)))
  1002. ;; (add-hook (kill-local-variable 'before-save-hook)
  1003. ;; 'js2-before-save)
  1004. ;; (add-hook 'before-save-hook
  1005. ;; 'my-indent-buffer
  1006. ;; nil
  1007. ;; t)
  1008. )
  1009. (add-to-list 'interpreter-mode-alist
  1010. '("node" . js-mode))
  1011. (add-hook 'haskell-mode-hook 'turn-on-haskell-indentation)
  1012. (with-eval-after-load 'uniquify
  1013. (setq uniquify-buffer-name-style 'post-forward-angle-brackets)
  1014. (setq uniquify-ignore-buffers-re "*[^*]+*")
  1015. (setq uniquify-min-dir-content 1))
  1016. (with-eval-after-load 'view
  1017. (defvar view-mode-map (make-sparse-keymap))
  1018. (define-key view-mode-map "j" 'scroll-up-line)
  1019. (define-key view-mode-map "k" 'scroll-down-line)
  1020. (define-key view-mode-map "v" 'toggle-read-only)
  1021. (define-key view-mode-map "q" 'bury-buffer)
  1022. ;; (define-key view-mode-map "/" 'nonincremental-re-search-forward)
  1023. ;; (define-key view-mode-map "?" 'nonincremental-re-search-backward)
  1024. ;; (define-key view-mode-map
  1025. ;; "n" 'nonincremental-repeat-search-forward)
  1026. ;; (define-key view-mode-map
  1027. ;; "N" 'nonincremental-repeat-search-backward)
  1028. (define-key view-mode-map "/" 'isearch-forward-regexp)
  1029. (define-key view-mode-map "?" 'isearch-backward-regexp)
  1030. (define-key view-mode-map "n" 'isearch-repeat-forward)
  1031. (define-key view-mode-map "N" 'isearch-repeat-backward)
  1032. (define-key view-mode-map (kbd "C-m") 'my-rgrep-symbol-at-point))
  1033. (global-set-key "\M-r" 'view-mode)
  1034. ;; (setq view-read-only t)
  1035. (with-eval-after-load 'term
  1036. (defvar term-raw-map (make-sparse-keymap))
  1037. (define-key term-raw-map (kbd "C-x")
  1038. (lookup-key (current-global-map)
  1039. (kbd "C-x"))))
  1040. (add-hook 'term-mode-hook
  1041. (lambda ()
  1042. ;; Stop current line highlighting
  1043. (set (make-local-variable (defvar hl-line-range-function))
  1044. (lambda () '(0 . 0)))
  1045. (set (make-local-variable 'scroll-margin)
  1046. 0)))
  1047. (add-hook 'Man-mode-hook
  1048. (lambda ()
  1049. (view-mode 1)
  1050. (setq truncate-lines nil)))
  1051. (set-variable 'Man-notify-method (if window-system
  1052. 'newframe
  1053. 'aggressive))
  1054. (set-variable 'woman-cache-filename (expand-file-name (concat user-emacs-directory
  1055. "woman_cache.el")))
  1056. ;; not work because man.el will be loaded when man called
  1057. (defalias 'man 'woman)
  1058. (add-to-list 'auto-mode-alist
  1059. '("tox\\.ini\\'" . conf-unix-mode))
  1060. (when (autoload-eval-lazily 'toml-mode)
  1061. (add-to-list 'auto-mode-alist
  1062. '("/tox\\.ini\\'" . toml-mode))
  1063. (add-to-list 'auto-mode-alist
  1064. '("/Pipfile\\'" . toml-mode))
  1065. (add-to-list 'auto-mode-alist
  1066. '("/poetry\\.lock\\'" . toml-mode))
  1067. )
  1068. (when (autoload-eval-lazily 'json-mode)
  1069. (add-to-list 'auto-mode-alist
  1070. '("/Pipfile\\.lock\\'" . json-mode)))
  1071. (add-hook 'go-mode-hook
  1072. (lambda()
  1073. (defvar go-mode-map)
  1074. (add-hook 'before-save-hook' 'gofmt-before-save)
  1075. (define-key go-mode-map (kbd "M-.") 'godef-jump)))
  1076. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1077. ;; buffers
  1078. (defvar bs-configurations)
  1079. (when (autoload-eval-lazily 'bs '(bs-show)
  1080. (add-to-list 'bs-configurations
  1081. '("specials" "^\\*" nil ".*" nil nil))
  1082. (add-to-list 'bs-configurations
  1083. '("files-and-specials" "^\\*" buffer-file-name ".*" nil nil))
  1084. (defvar bs-mode-map)
  1085. (defvar bs-current-configuration)
  1086. (define-key bs-mode-map (kbd "t")
  1087. ;; TODO: fix toggle feature
  1088. (lambda ()
  1089. (interactive)
  1090. (if (string= "specials"
  1091. bs-current-configuration)
  1092. (bs-set-configuration "files")
  1093. (bs-set-configuration "specials"))
  1094. (bs-refresh)
  1095. (bs-message-without-log "%s"
  1096. (bs--current-config-message))))
  1097. ;; (setq bs-configurations (list
  1098. ;; '("processes" nil get-buffer-process ".*" nil nil)
  1099. ;; '("files-and-scratch" "^\\*scratch\\*$" nil nil
  1100. ;; bs-visits-non-file bs-sort-buffer-interns-are-last)))
  1101. )
  1102. (defalias 'list-buffers 'bs-show)
  1103. (set-variable 'bs-default-configuration "files-and-specials")
  1104. (set-variable 'bs-default-sort-name "by nothing")
  1105. (add-hook 'bs-mode-hook
  1106. (lambda ()
  1107. (set (make-local-variable 'scroll-margin) 0))))
  1108. ;;(iswitchb-mode 1)
  1109. (icomplete-mode)
  1110. (defun iswitchb-buffer-display-other-window ()
  1111. "Do iswitchb in other window."
  1112. (interactive)
  1113. (let ((iswitchb-default-method 'display))
  1114. (call-interactively 'iswitchb-buffer)))
  1115. ;; buffer killing
  1116. ;; (defun my-delete-window-killing-buffer () nil)
  1117. (defun my-query-kill-current-buffer ()
  1118. "Interactively kill current buffer."
  1119. (interactive)
  1120. (if (y-or-n-p (concat "kill current buffer? :"))
  1121. (kill-buffer (current-buffer))))
  1122. ;;(global-set-key "\C-xk" 'my-query-kill-current-buffer)
  1123. (substitute-key-definition 'kill-buffer
  1124. 'my-query-kill-current-buffer
  1125. global-map)
  1126. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1127. ;; recentf-mode
  1128. (set-variable 'recentf-save-file (expand-file-name (concat user-emacs-directory
  1129. "recentf")))
  1130. (set-variable 'recentf-max-menu-items 20)
  1131. (set-variable 'recentf-max-saved-items 30)
  1132. (set-variable 'recentf-show-file-shortcuts-flag nil)
  1133. (set-variable 'recentf-auto-cleanup 3)
  1134. ;; (safe-require-or-eval 'sync-recentf)
  1135. ;; (when (safe-require-or-eval 'recentf)
  1136. ;; (add-to-list 'recentf-exclude
  1137. ;; (regexp-quote recentf-save-file))
  1138. ;; (add-to-list 'recentf-exclude
  1139. ;; (regexp-quote (expand-file-name user-emacs-directory)))
  1140. ;; (add-to-list 'recentf-exclude
  1141. ;; "/sync-recentf-marker\\'")
  1142. ;; (define-key ctl-x-map (kbd "C-r") 'recentf-open-files)
  1143. ;; (remove-hook 'find-file-hook
  1144. ;; 'recentf-track-opened-file)
  1145. ;; (defun my-recentf-load-track-save-list ()
  1146. ;; "Load current recentf list from file, track current visiting file, then save
  1147. ;; the list."
  1148. ;; (recentf-load-list)
  1149. ;; (recentf-track-opened-file)
  1150. ;; (recentf-save-list))
  1151. ;; (add-hook 'find-file-hook
  1152. ;; 'my-recentf-load-track-save-list)
  1153. ;; (add-hook 'kill-emacs-hook
  1154. ;; 'recentf-load-list)
  1155. ;; ;;(run-with-idle-timer 5 t 'recentf-save-list)
  1156. ;; ;; (add-hook 'find-file-hook
  1157. ;; ;; (lambda ()
  1158. ;; ;; (recentf-add-file default-directory)))
  1159. ;; (when (autoload-eval-lazily 'recentf-show)
  1160. ;; (define-key ctl-x-map (kbd "C-r") 'recentf-show)
  1161. ;; ;; (add-hook 'recentf-show-before-listing-hook
  1162. ;; ;; 'recentf-load-list)
  1163. ;; )
  1164. ;; (recentf-mode 1)
  1165. ;; (define-key recentf-dialog-mode-map (kbd "<up>") 'previous-line)
  1166. ;; (define-key recentf-dialog-mode-map (kbd "<down>") 'next-line)
  1167. ;; (define-key recentf-dialog-mode-map "p" 'previous-line)
  1168. ;; (define-key recentf-dialog-mode-map "n" 'next-line)
  1169. ;; (add-hook 'recentf-dialog-mode-hook
  1170. ;; (lambda ()
  1171. ;; ;; (recentf-save-list)
  1172. ;; ;; (define-key recentf-dialog-mode-map (kbd "C-x C-f")
  1173. ;; ;; 'my-recentf-cd-and-find-file)
  1174. ;; (cd "~/"))))
  1175. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1176. ;; dired
  1177. (defun my-file-head (filename &optional n)
  1178. "Return list of first N lines of file FILENAME."
  1179. ;; TODO: Fix for janapese text
  1180. ;; TODO: Fix for short text
  1181. (let ((num (or n 10))
  1182. (size 100)
  1183. (beg 0)
  1184. (end 0)
  1185. (result '())
  1186. (read -1))
  1187. (with-temp-buffer
  1188. (erase-buffer)
  1189. (while (or (<= (count-lines (point-min)
  1190. (point-max))
  1191. num)
  1192. (eq read 0))
  1193. (setq end (+ beg size))
  1194. (setq read (nth 1 (insert-file-contents-literally filename
  1195. nil
  1196. beg
  1197. end)))
  1198. (goto-char (point-max))
  1199. (setq beg (+ beg size)))
  1200. (goto-char (point-min))
  1201. (while (< (length result) num)
  1202. (let ((start (point)))
  1203. (forward-line 1)
  1204. (setq result
  1205. `(,@result ,(buffer-substring-no-properties start
  1206. (point))))))
  1207. result
  1208. ;; (buffer-substring-no-properties (point-min)
  1209. ;; (progn
  1210. ;; (forward-line num)
  1211. ;; (point)))
  1212. )))
  1213. ;; (apply 'concat (my-file-head "./shrc" 10)
  1214. (defun my-dired-echo-file-head (arg)
  1215. "Echo head of current file.
  1216. ARG is num to show, or defaults to 7."
  1217. (interactive "P")
  1218. (let ((f (dired-get-filename)))
  1219. (message "%s"
  1220. (apply 'concat
  1221. (my-file-head f
  1222. 7)))))
  1223. (defun my-dired-diff ()
  1224. "Show diff of marked file and file of current line."
  1225. (interactive)
  1226. (let ((files (dired-get-marked-files nil nil nil t)))
  1227. (if (eq (car files)
  1228. t)
  1229. (diff (cadr files) (dired-get-filename))
  1230. (message "One file must be marked!"))))
  1231. (defun dired-get-file-info ()
  1232. "Print information of current line file."
  1233. (interactive)
  1234. (let ((f (shell-quote-argument (dired-get-filename t))))
  1235. (if (file-directory-p f)
  1236. (progn
  1237. (message "Calculating disk usage...")
  1238. (shell-command (concat "du -hsD "
  1239. f)))
  1240. (shell-command (concat "file "
  1241. f)))))
  1242. (defun my-dired-scroll-up ()
  1243. "Scroll up."
  1244. (interactive)
  1245. (my-dired-previous-line (- (window-height) 1)))
  1246. (defun my-dired-scroll-down ()
  1247. "Scroll down."
  1248. (interactive)
  1249. (my-dired-next-line (- (window-height) 1)))
  1250. ;; (defun my-dired-forward-line (arg)
  1251. ;; ""
  1252. ;; (interactive "p"))
  1253. (defun my-dired-previous-line (arg)
  1254. "Move ARG lines up."
  1255. (interactive "p")
  1256. (if (> arg 0)
  1257. (progn
  1258. (if (eq (line-number-at-pos)
  1259. 1)
  1260. (goto-char (point-max))
  1261. (forward-line -1))
  1262. (my-dired-previous-line (if (or (dired-get-filename nil t)
  1263. (dired-get-subdir))
  1264. (- arg 1)
  1265. arg)))
  1266. (dired-move-to-filename)))
  1267. (defun my-dired-next-line (arg)
  1268. "Move ARG lines down."
  1269. (interactive "p")
  1270. (if (> arg 0)
  1271. (progn
  1272. (if (eq (point)
  1273. (point-max))
  1274. (goto-char (point-min))
  1275. (forward-line 1))
  1276. (my-dired-next-line (if (or (dired-get-filename nil t)
  1277. (dired-get-subdir))
  1278. (- arg 1)
  1279. arg)))
  1280. (dired-move-to-filename)))
  1281. (defun my-tramp-remote-find-file (f)
  1282. "Open F."
  1283. (interactive (list (read-file-name "My Find File Tramp: "
  1284. "/scp:"
  1285. nil ;; "/scp:"
  1286. (confirm-nonexistent-file-or-buffer))))
  1287. (find-file f))
  1288. ;;http://bach.istc.kobe-u.ac.jp/lect/tamlab/ubuntu/emacs.html
  1289. (if (eq window-system 'mac)
  1290. (setq dired-listing-switches "-lhF")
  1291. (setq dired-listing-switches "-lhF --time-style=long-iso")
  1292. )
  1293. (setq dired-listing-switches "-lhF")
  1294. ;; when using dired-find-alternate-file
  1295. ;; reuse current dired buffer for the file to open
  1296. ;; (put 'dired-find-alternate-file 'disabled nil)
  1297. (set-variable 'dired-ls-F-marks-symlinks t)
  1298. (set-variable 'ls-lisp-use-insert-directory-program nil) ; always use ls-lisp
  1299. (set-variable 'ls-lisp-dirs-first t)
  1300. (set-variable 'ls-lisp-use-localized-time-format t)
  1301. (set-variable 'ls-lisp-format-time-list
  1302. '("%Y-%m-%d %H:%M"
  1303. "%Y-%m-%d "))
  1304. (set-variable 'dired-dwim-target t)
  1305. (set-variable 'dired-isearch-filenames t)
  1306. (set-variable 'dired-hide-details-hide-symlink-targets nil)
  1307. (set-variable 'dired-hide-details-hide-information-lines nil)
  1308. (set-variable 'dired-deletion-confirmer 'y-or-n-p)
  1309. (set-variable 'dired-recursive-deletes 'always)
  1310. ;; (add-hook 'dired-after-readin-hook
  1311. ;; 'my-replace-nasi-none)
  1312. (with-eval-after-load 'dired
  1313. (safe-require-or-eval 'ls-lisp)
  1314. (defvar dired-mode-map (make-sparse-keymap))
  1315. ;; dired-do-chgrp sometimes cause system hung
  1316. (define-key dired-mode-map "G" 'ignore)
  1317. (define-key dired-mode-map "e" 'wdired-change-to-wdired-mode)
  1318. (define-key dired-mode-map "i" 'dired-get-file-info)
  1319. (define-key dired-mode-map "f" 'find-file)
  1320. (define-key dired-mode-map "!" 'shell-command)
  1321. (define-key dired-mode-map "&" 'async-shell-command)
  1322. (define-key dired-mode-map "X" 'dired-do-async-shell-command)
  1323. (define-key dired-mode-map "=" 'my-dired-diff)
  1324. (define-key dired-mode-map "B" 'gtkbm-add-current-dir)
  1325. (define-key dired-mode-map "b" 'gtkbm)
  1326. (define-key dired-mode-map "h" 'my-dired-echo-file-head)
  1327. (define-key dired-mode-map (kbd "TAB") 'other-window)
  1328. ;; (define-key dired-mode-map "P" 'my-dired-do-pack-or-unpack)
  1329. (define-key dired-mode-map "/" 'dired-isearch-filenames)
  1330. (define-key dired-mode-map (kbd "DEL") 'dired-up-directory)
  1331. (define-key dired-mode-map (kbd "C-h") 'dired-up-directory)
  1332. (substitute-key-definition 'dired-next-line
  1333. 'my-dired-next-line
  1334. dired-mode-map)
  1335. (substitute-key-definition 'dired-previous-line
  1336. 'my-dired-previous-line
  1337. dired-mode-map)
  1338. ;; (define-key dired-mode-map (kbd "C-p") 'my-dired-previous-line)
  1339. ;; (define-key dired-mode-map (kbd "p") 'my-dired-previous-line)
  1340. ;; (define-key dired-mode-map (kbd "C-n") 'my-dired-next-line)
  1341. ;; (define-key dired-mode-map (kbd "n") 'my-dired-next-line)
  1342. (define-key dired-mode-map (kbd "<left>") 'my-dired-scroll-up)
  1343. (define-key dired-mode-map (kbd "<right>") 'my-dired-scroll-down)
  1344. (define-key dired-mode-map (kbd "ESC p") 'my-dired-scroll-up)
  1345. (define-key dired-mode-map (kbd "ESC n") 'my-dired-scroll-down)
  1346. (add-hook 'dired-mode-hook
  1347. (lambda ()
  1348. (when (fboundp 'dired-hide-details-mode)
  1349. (dired-hide-details-mode t)
  1350. (local-set-key "l" 'dired-hide-details-mode))
  1351. (let ((file "._Icon\015"))
  1352. (when nil
  1353. '(file-readable-p file)
  1354. (delete-file file)))))
  1355. (when (autoload-eval-lazily 'pack '(dired-do-pack-or-unpack pack-pack))
  1356. (with-eval-after-load 'dired
  1357. (define-key dired-mode-map "P" 'pack-dired-dwim)))
  1358. (when (autoload-eval-lazily 'dired-list-all-mode)
  1359. (setq dired-listing-switches "-lhF")
  1360. (with-eval-after-load 'dired
  1361. (define-key dired-mode-map "a" 'dired-list-all-mode))))
  1362. (when (autoload-eval-lazily 'dired-filter)
  1363. (add-hook 'dired-mode-hook
  1364. 'dired-filter-mode))
  1365. ;; Currently disabled in favor of dired-from-git-ls-files
  1366. ;; (define-key ctl-x-map "f" 'find-dired)
  1367. ;; It works!
  1368. ;; (pop-to-buffer (dired-noselect '("." "shrc" "emacs.el")))
  1369. (defun my-dired-git-ls-files (args)
  1370. "Dired from git ls-files."
  1371. (interactive "sgit ls-files args: ")
  1372. (pop-to-buffer-same-window
  1373. (dired-noselect `(,default-directory
  1374. ,@(split-string (shell-command-to-string (concat "git ls-files -z " args))
  1375. "\0" t))
  1376. ""))
  1377. )
  1378. (define-key ctl-x-map (kbd "f") 'my-dired-git-ls-files)
  1379. (with-eval-after-load 'dired
  1380. (defvar dired-mode-map (make-sparse-keymap))
  1381. (define-key dired-mode-map "G" 'my-dired-git-ls-files))
  1382. ;; (define-minor-mode my-dired-glob-filter)
  1383. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1384. ;; misc funcs
  1385. (defalias 'qcalc 'quick-calc)
  1386. (defun memo (&optional dir)
  1387. "Open memo.txt in DIR."
  1388. (interactive)
  1389. (pop-to-buffer (find-file-noselect (concat (if dir
  1390. (file-name-as-directory dir)
  1391. "")
  1392. "memo.txt"))))
  1393. (set (defvar my-rgrep-alist nil
  1394. "Alist of rgrep command.
  1395. Each element is in the form like (NAME SEXP COMMAND), where SEXP returns the
  1396. condition to choose COMMAND when evaluated.")
  1397. `(
  1398. ;; ripgrep
  1399. ("rg"
  1400. (executable-find "rg")
  1401. "rg --hidden --no-heading --smart-case ")
  1402. ;; git grep
  1403. ("gitgrep"
  1404. (eq 0
  1405. (shell-command "git rev-parse --git-dir"))
  1406. "git --no-pager -c color.grep=always grep -nH -e ")
  1407. ;; sift
  1408. ("sift"
  1409. (executable-find "sift")
  1410. ("sift --binary-skip --filename --line-number --git --smart-case "))
  1411. ;; the silver searcher
  1412. ("ag"
  1413. (executable-find "ag")
  1414. "ag --nogroup --nopager --filename ")
  1415. ;; ack
  1416. ("ack"
  1417. (executable-find "ack")
  1418. "ack --nogroup --nopager --with-filename ")
  1419. ;; gnu global
  1420. ("global"
  1421. (and (require 'ggtags nil t)
  1422. (executable-find "global")
  1423. (ggtags-current-project-root))
  1424. "global --result grep ")
  1425. ;; grep
  1426. ("grep"
  1427. t
  1428. ,(concat "find . "
  1429. "-path '*/.git' -prune -o "
  1430. "-path '*/.svn' -prune -o "
  1431. "-type f -print0 | "
  1432. "xargs -0 grep -nH -e "))
  1433. )
  1434. )
  1435. (defvar my-rgrep-default nil
  1436. "Default command name for my-rgrep.")
  1437. (defun my-rgrep-grep-command (&optional name alist)
  1438. "Return recursive grep command for current directory or nil.
  1439. If NAME is given, use that without testing.
  1440. Commands are searched from ALIST."
  1441. (if alist
  1442. (if name
  1443. ;; if name is given search that from alist and return the command
  1444. (nth 2 (assoc name
  1445. alist))
  1446. ;; if name is not given try test in 1th elem
  1447. (let ((car (car alist))
  1448. (cdr (cdr alist)))
  1449. (if (eval (nth 1 car))
  1450. ;; if the condition is true return the command
  1451. (nth 2 car)
  1452. ;; try next one
  1453. (and cdr
  1454. (my-rgrep-grep-command name cdr)))))
  1455. ;; if alist is not given set default value
  1456. (my-rgrep-grep-command name my-rgrep-alist)))
  1457. (defun my-rgrep (command-args)
  1458. "My recursive grep. Run COMMAND-ARGS.
  1459. If prefix argument is given, use current symbol as default search target
  1460. and search from projectile root (if projectile is available)."
  1461. (interactive (let ((cmd (my-rgrep-grep-command my-rgrep-default
  1462. nil)))
  1463. (if cmd
  1464. (list (read-shell-command "grep command: "
  1465. (concat cmd
  1466. (if current-prefix-arg
  1467. (thing-at-point 'symbol t)
  1468. ""))
  1469. 'grep-find-history))
  1470. (error "My-Rgrep: Command for rgrep not found")
  1471. )))
  1472. (if (and current-prefix-arg
  1473. (safe-require-or-eval 'projectile)
  1474. (projectile-project-p))
  1475. (projectile-with-default-dir (projectile-project-root)
  1476. (compilation-start command-args
  1477. 'grep-mode))
  1478. (compilation-start command-args
  1479. 'grep-mode)))
  1480. (defun my-rgrep-thing-at-point-projectile-root ()
  1481. "My recursive grep to find thing at point from project root."
  1482. (interactive)
  1483. (let* ((cmd (my-rgrep-grep-command my-rgrep-default
  1484. nil))
  1485. (command-args
  1486. (if cmd
  1487. (concat cmd
  1488. (or (thing-at-point 'symbol t)
  1489. (error "No symbol at point")))
  1490. (error "My-Rgrep: Command for rgrep not found"))))
  1491. (if (safe-require-or-eval 'projectile)
  1492. (projectile-with-default-dir (or (projectile-project-root)
  1493. default-directory)
  1494. (compilation-start command-args
  1495. 'grep-mode))
  1496. (compilation-start command-args
  1497. 'grep-mode))))
  1498. (defmacro define-my-rgrep (name)
  1499. "Define rgrep for NAME."
  1500. `(defun ,(intern (concat "my-rgrep-"
  1501. name)) ()
  1502. ,(format "My recursive grep by %s."
  1503. name)
  1504. (interactive)
  1505. (let ((my-rgrep-default ,name))
  1506. (if (called-interactively-p 'any)
  1507. (call-interactively 'my-rgrep)
  1508. (error "Not intended to be called noninteractively. Use `my-rgrep'"))))
  1509. )
  1510. (define-my-rgrep "ack")
  1511. (define-my-rgrep "ag")
  1512. (define-my-rgrep "rg")
  1513. (define-my-rgrep "sift")
  1514. (define-my-rgrep "gitgrep")
  1515. (define-my-rgrep "grep")
  1516. (define-my-rgrep "global")
  1517. (define-key ctl-x-map "s" 'my-rgrep)
  1518. (define-key ctl-x-map "." 'my-rgrep-thing-at-point-projectile-root)
  1519. (defun my-occur (regexp &optional region)
  1520. "My occur command to search REGEXP."
  1521. (interactive (list (read-string "List lines matching regexp: "
  1522. (thing-at-point 'symbol t))))
  1523. (occur regexp nil region))
  1524. (define-key ctl-x-map (kbd "C-o") 'my-occur)
  1525. (set-variable 'dumb-jump-prefer-searcher 'rg)
  1526. (defalias 'make 'compile)
  1527. (define-key ctl-x-map "c" 'compile)
  1528. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1529. ;; editorconfig-auto-apply
  1530. (define-minor-mode editorconfig-auto-apply-mode
  1531. "When saving .editorconfig file update buffer configs."
  1532. :global t
  1533. :lighter ""
  1534. (if editorconfig-auto-apply-mode
  1535. (add-hook 'after-save-hook
  1536. 'editorconfig-auto-apply-mode--run)
  1537. (remove-hook 'after-save-hook
  1538. 'editorconfig-auto-apply-mode--run)))
  1539. (defun editorconfig-auto-apply-mode--run ()
  1540. "When saving .editorconfig file walk all buffers and update configs."
  1541. (when (eq major-mode
  1542. 'editorconfig-conf-mode)
  1543. (let ((dir (file-name-directory buffer-file-name)))
  1544. (cl-dolist (buf (buffer-list))
  1545. (when (and (buffer-file-name buf)
  1546. (file-in-directory-p (buffer-file-name buf)
  1547. dir))
  1548. (with-current-buffer buf
  1549. (editorconfig-mode-apply)))))))
  1550. (editorconfig-auto-apply-mode 1)
  1551. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1552. ;; recently
  1553. (defgroup recently nil
  1554. "Recently visited files"
  1555. :tag "Recently"
  1556. :prefix "recently-"
  1557. :group 'tools)
  1558. (defcustom recently-file
  1559. (concat user-emacs-directory
  1560. "recently.el")
  1561. "Recently file."
  1562. :type 'string
  1563. :group 'recently)
  1564. (defcustom recently-max
  1565. 100
  1566. "Recently list max length."
  1567. :type 'int
  1568. :group 'recently)
  1569. (defcustom recently-excludes
  1570. '()
  1571. "List of regexps for filenames excluded from the recent list."
  1572. :type '(repeat string)
  1573. :group 'recently)
  1574. (add-to-list 'recently-excludes
  1575. (eval-when-compile (rx "/COMMIT_EDITMSG" eot)))
  1576. (defvar recently-list
  1577. '()
  1578. "Recently list.")
  1579. (defvar recently-file-mtime
  1580. nil
  1581. "Modified time of file when last read file.")
  1582. (defun recently-write ()
  1583. "Write to file."
  1584. ;; Failsafe to avoid purging all existing entries
  1585. (cl-assert recently-list)
  1586. (with-temp-buffer
  1587. (prin1 recently-list
  1588. (current-buffer))
  1589. (write-region (point-min)
  1590. (point-max)
  1591. recently-file)))
  1592. (defun recently-read ()
  1593. "Read file."
  1594. (when (file-readable-p recently-file)
  1595. (with-temp-buffer
  1596. (insert-file-contents recently-file)
  1597. (goto-char (point-min))
  1598. (setq recently-list
  1599. (read (current-buffer))))
  1600. (setq recently-file-mtime
  1601. (nth 5
  1602. (file-attributes recently-file)))))
  1603. (defun recently-reload ()
  1604. "Reload file and update `recently-list' value.
  1605. This function does nothing when there is no update to `recently-file' since last
  1606. read."
  1607. (when (and (file-readable-p recently-file)
  1608. (not (equal recently-file-mtime
  1609. (nth 5
  1610. (file-attributes recently-file)))))
  1611. (recently-read)
  1612. (cl-assert (equal recently-file-mtime
  1613. (nth 5
  1614. (file-attributes recently-file))))))
  1615. (defun recently-add (path)
  1616. "Add PATH to list."
  1617. (cl-assert (string= path
  1618. (expand-file-name path)))
  1619. (when (cl-loop for re in recently-excludes
  1620. if (string-match re path) return nil
  1621. finally return t)
  1622. (recently-reload)
  1623. (let* ((l (cl-copy-list recently-list))
  1624. (l (delete path
  1625. l))
  1626. (l (cl-loop for e in l
  1627. unless (file-in-directory-p path e)
  1628. collect e))
  1629. (l (cons path
  1630. l))
  1631. (l (recently--truncate l
  1632. recently-max)))
  1633. (unless (equal recently-list
  1634. l)
  1635. (setq recently-list l)
  1636. (recently-write)
  1637. (setq recently-file-mtime
  1638. (nth 5
  1639. (file-attributes recently-file)))))))
  1640. (defun recently--truncate (list len)
  1641. "Truncate LIST to LEN."
  1642. (if (> (length list)
  1643. len)
  1644. (cl-subseq list
  1645. 0
  1646. len)
  1647. list))
  1648. (defun recently-find-file-hook ()
  1649. "Add current file."
  1650. (when buffer-file-name
  1651. (recently-add buffer-file-name)))
  1652. (defun recently-dired-mode-hook ()
  1653. "Add current directory."
  1654. (recently-add (expand-file-name default-directory)))
  1655. (add-hook 'find-file-hook
  1656. 'recently-find-file-hook)
  1657. (add-hook 'dired-mode-hook
  1658. 'recently-dired-mode-hook)
  1659. ;;;;;;;;;;;;;;;;
  1660. ;; recently-show
  1661. (defvar recently-show-window-configuration nil
  1662. "Used for internal")
  1663. (defvar recently-show-abbreviate t
  1664. "Non-nil means use `abbreviate-file-name' when listing recently opened files.")
  1665. ;;;###autoload
  1666. (defun recently-show (&optional buffer-name)
  1667. "Show simplified list of recently opened files.
  1668. If optional argument BUFFER-NAME is non-nil, it is a buffer name to
  1669. use for the buffer. It defaults to \"*recetf-show*\"."
  1670. ;; If optional argument FILES is non-nil, it is a list of recently-opened
  1671. ;; files to choose from. It defaults to the whole recent list.
  1672. (interactive)
  1673. (let ((bf (recently-show--create-buffer-tabulated buffer-name)))
  1674. (if bf
  1675. (progn
  1676. (setq recently-show-window-configuration (current-window-configuration))
  1677. (pop-to-buffer bf))
  1678. (message "No recent file!"))))
  1679. (defun recently-show--create-buffer-tabulated (&optional buffer-name)
  1680. "Create buffer listing recently files."
  1681. (let ((bname (or buffer-name
  1682. "*Recently*")))
  1683. (when (get-buffer bname)
  1684. (kill-buffer bname))
  1685. (with-current-buffer (get-buffer-create bname)
  1686. ;; (setq tabulated-list-sort-key (cons "Name" nil))
  1687. (recently-show--set-tabulated-list-mode-variables)
  1688. (recently-show-tabulated-mode)
  1689. (current-buffer))))
  1690. (defun recently-show--set-tabulated-list-mode-variables ()
  1691. "Set variables for `tabulated-list-mode'."
  1692. (recently-reload)
  1693. (setq tabulated-list-entries
  1694. (mapcar (lambda (f)
  1695. (list f
  1696. (vector (file-name-nondirectory f)
  1697. (if recently-show-abbreviate
  1698. (abbreviate-file-name f)
  1699. f))))
  1700. recently-list
  1701. ))
  1702. (let ((max
  1703. (apply 'max
  1704. (mapcar (lambda (l)
  1705. (length (elt (cadr l) 0)))
  1706. tabulated-list-entries))))
  1707. (setq tabulated-list-format
  1708. `[("Name"
  1709. ,(min max
  1710. 30)
  1711. t)
  1712. ("Full Path" 0 t)])))
  1713. (defun recently-show-tabulated-find-file ()
  1714. "Find file at point."
  1715. (interactive)
  1716. (let ((f (tabulated-list-get-id)))
  1717. (when f
  1718. (recently-show-tabulated-close)
  1719. (find-file f))))
  1720. (defun recently-show-tabulated-view-file ()
  1721. "View file at point."
  1722. (interactive)
  1723. (let ((f (tabulated-list-get-id)))
  1724. (when f
  1725. (recently-show-tabulated-close)
  1726. (view-file f))))
  1727. (defun recently-show-tabulated-dired()
  1728. "Open dired buffer of directory at point."
  1729. (interactive)
  1730. (let ((f (tabulated-list-get-id)))
  1731. (when f
  1732. (recently-show-tabulated-close)
  1733. (dired (if (file-directory-p f)
  1734. f
  1735. (or (file-name-directory f)
  1736. "."))))))
  1737. (defvar recently-show-tabulated-mode-map
  1738. (let ((map (make-sparse-keymap)))
  1739. (suppress-keymap map)
  1740. (define-key map (kbd "C-m") 'recently-show-tabulated-find-file)
  1741. (define-key map "v" 'recently-show-tabulated-view-file)
  1742. (define-key map "@" 'recently-show-tabulated-dired)
  1743. (define-key map (kbd "C-g") 'recently-show-tabulated-close)
  1744. (define-key map "/" 'isearch-forward)
  1745. map))
  1746. (define-derived-mode recently-show-tabulated-mode tabulated-list-mode "Recently-Show"
  1747. "Major mode for browsing recently opened files and directories."
  1748. (setq tabulated-list-padding 2)
  1749. (add-hook 'tabulated-list-revert-hook
  1750. 'recently-show--set-tabulated-list-mode-variables
  1751. nil
  1752. t)
  1753. (tabulated-list-init-header)
  1754. (tabulated-list-print nil nil))
  1755. (defun recently-show-tabulated-close ()
  1756. "Close recently-show window."
  1757. (interactive)
  1758. (kill-buffer (current-buffer))
  1759. (set-window-configuration recently-show-window-configuration))
  1760. (define-key ctl-x-map (kbd "C-r") 'recently-show)
  1761. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1762. ;; git-worktree
  1763. (defun git-worktree-get-current-trees ()
  1764. "Get current worktree list."
  1765. (with-temp-buffer
  1766. (let ((status (call-process "git"
  1767. nil
  1768. t
  1769. nil
  1770. "worktree" "list" "--porcelain")))
  1771. (cl-assert (eq status 0)))
  1772. (goto-char (point-min))
  1773. (let ((trees nil))
  1774. (save-match-data
  1775. (while (not (eq (point) (point-max)))
  1776. (let ((worktree nil)
  1777. (head nil)
  1778. (branch nil))
  1779. (while (re-search-forward "^\\([^ ]+\\) \\(.*\\)$" (point-at-eol) t)
  1780. (pcase (match-string 1)
  1781. ("worktree" (setq worktree (match-string 2)))
  1782. ("HEAD" (setq head (match-string 2)))
  1783. ("branch" (setq branch (match-string 2))))
  1784. (forward-line 1)
  1785. (goto-char (point-at-bol)))
  1786. (setq trees `(,@trees
  1787. (:worktree ,worktree :head ,head :branch ,branch)))
  1788. (forward-line 1)
  1789. (goto-char (point-at-bol)))
  1790. ))
  1791. trees)))
  1792. (defun git-worktree--call-process (args)
  1793. "Start git process synchronously with ARGS.
  1794. Raise error when git process ends with non-zero status.
  1795. Any output will be written to current buffer."
  1796. (let ((status (apply 'call-process
  1797. "git"
  1798. nil
  1799. t
  1800. nil
  1801. args)))
  1802. (cl-assert (eq status 0)
  1803. nil
  1804. (buffer-substring-no-properties (point-min) (point-max)))))
  1805. (defun git-worktree--get-repository-root (dir)
  1806. "Resolve repository root of DIR.
  1807. If DIR is not inside of any git repository, signal an error."
  1808. (cl-assert (file-directory-p dir))
  1809. (with-temp-buffer
  1810. (cd dir)
  1811. (let ((status (call-process "git"
  1812. nil
  1813. t
  1814. nil
  1815. "rev-parse" "--show-toplevel")))
  1816. (cl-assert (eq status 0)
  1817. nil
  1818. (buffer-substring-no-properties (point-min) (point-max))))
  1819. (goto-char (point-min))
  1820. (buffer-substring-no-properties (point-at-bol) (point-at-eol))))
  1821. ;;(git-worktree--get-repository-root default-directory)
  1822. (defun git-worktree-open-noselect (&optional directory)
  1823. "Open git worktree list buffer.
  1824. If optional arg DIRECTORY is given change current directory to there before
  1825. initializing."
  1826. (setq directory (expand-file-name (or directory
  1827. default-directory)))
  1828. (cl-assert (file-directory-p directory))
  1829. (let* ((root (git-worktree--get-repository-root directory))
  1830. (name (file-name-nondirectory root))
  1831. (bname (format "*GitWorktree<%s>*" name)))
  1832. (with-current-buffer (get-buffer-create bname)
  1833. (cd root)
  1834. (let ((trees (git-worktree-get-current-trees)))
  1835. (setq tabulated-list-entries
  1836. (mapcar (lambda (e)
  1837. (list e
  1838. (vector
  1839. (concat (file-relative-name (plist-get e :worktree))
  1840. "/")
  1841. (or (plist-get e :branch) "")
  1842. (plist-get e :head)
  1843. )))
  1844. trees))
  1845. (let ((branch-max-size
  1846. (apply 'max
  1847. (cl-loop for e in tabulated-list-entries
  1848. collect (length (elt (cadr e) 1)))))
  1849. (worktree-max-size
  1850. (apply 'max
  1851. (length "Worktree")
  1852. (cl-loop for e in tabulated-list-entries
  1853. collect (length (elt (cadr e) 0))))))
  1854. (setq tabulated-list-format
  1855. `[
  1856. ("Worktree" ,worktree-max-size t)
  1857. ("Branch" ,branch-max-size t)
  1858. ("Head" -1 t)
  1859. ])))
  1860. (git-worktree-mode)
  1861. (current-buffer))))
  1862. ;; ((:worktree "/Users/10sr/.dotfiles" :head "5e7457a8d49ef6a517cdf39d038ba5fdf98dc68e" :branch "refs/heads/master") (:worktree "/Users/10sr/.dotfiles/b1" :head "fa7d868076d807692e35f82ae23596c903fd1117" :branch "refs/heads/b1"))
  1863. (defun git-worktree-open (&optional directory)
  1864. "Open git worktree list buffer.
  1865. If optional arg DIRECTORY is given change current directory to there before
  1866. initializing."
  1867. (interactive)
  1868. (let ((bf (git-worktree-open-noselect directory)))
  1869. (pop-to-buffer bf)))
  1870. (defalias 'git-worktree 'git-worktree-open)
  1871. (defun git-worktree-mode-go ()
  1872. "Go to worktree directory at point."
  1873. (interactive)
  1874. (let* ((id (tabulated-list-get-id))
  1875. (path (plist-get id :worktree)))
  1876. (when path
  1877. (if (file-directory-p path)
  1878. (dired path)
  1879. (error "Directory not found: %s" path)))))
  1880. (defun git-worktree-mode-move ())
  1881. (defvar git-worktree-mode-map
  1882. (let ((map (make-sparse-keymap)))
  1883. (suppress-keymap map)
  1884. (define-key map (kbd "C-m") 'git-worktree-mode-go)
  1885. (define-key map "R" 'git-worktree-mode-move)
  1886. (define-key map "D" 'git-worktree-mode-remove)
  1887. (define-key map (kbd "C-g") 'git-worktree-mode-close)
  1888. (define-key map "/" 'isearch-forward)
  1889. map))
  1890. (define-derived-mode git-worktree-mode tabulated-list-mode "Git-Worktrees"
  1891. "Major mode for browsing recently opened files and directories."
  1892. (setq tabulated-list-padding 2)
  1893. ;; TODO: Implement revert
  1894. ;; (add-hook 'tabulated-list-revert-hook 'git-worktree-mode-reload nil t)
  1895. (tabulated-list-init-header)
  1896. (tabulated-list-print nil nil))
  1897. ;; Local Variables:
  1898. ;; flycheck-disabled-checkers: (emacs-lisp-checkdoc)
  1899. ;; flycheck-checker: emacs-lisp
  1900. ;; End:
  1901. ;;; emancs.el ends here