diff --git a/emacs.d/autocomplete.el b/emacs.d/autocomplete.el new file mode 100644 index 0000000..85851de --- /dev/null +++ b/emacs.d/autocomplete.el @@ -0,0 +1,14 @@ +(require 'semantic) + +(global-company-mode) +;;Setup company-mode +(setq company-dabbrev-downcase nil) +(setq company-idle-delay 0) +(setq company-minimum-prefix-length 1) + + +(add-hook 'after-init-hook #'global-flycheck-mode) +(setq flycheck-flake8-maximum-line-length 500) + +(semantic-mode 1) +(global-semantic-stickyfunc-mode 1) diff --git a/emacs.d/custom.el b/emacs.d/custom.el new file mode 100644 index 0000000..bc532b1 --- /dev/null +++ b/emacs.d/custom.el @@ -0,0 +1,43 @@ +(require 'saveplace) +(require 'midnight) +(require 'helm-projectile) + +(if (daemonp) + (add-hook 'after-make-frame-functions + (lambda (frame) + (select-frame frame) + (load-theme 'material t))) + (load-theme 'material t)) +;;(load-theme 'material t) + +(setq-default save-place t) +(setq save-place-file "~/.emacs.d/saveplace") + + +(add-hook 'eww-mode-hook 'scroll-lock-mode) + +;;cleanup buffers +(setq clean-buffer-list-delay-special 900) +(defvar clean-buffer-list-timer nil + "Stores clean-buffer-list timer if there is one. You can disable clean-buffer-list by (cancel-timer clean-buffer-list-timer).") +(setq clean-buffer-list-timer (run-at-time t 7200 'clean-buffer-list)) +;; kill everything, clean-buffer-list is very intelligent at not killing +;; unsaved buffer. +(setq clean-buffer-list-kill-regexps '("^.*$")) + +;Enable windmove +(windmove-default-keybindings) + +(add-hook 'prog-mode-hook 'rainbow-delimiters-mode) + +;;Enable powerline +(powerline-center-theme) +(setq powerline-default-separator 'slant) + +(dumb-jump-mode) +(setq dumb-jump-selector 'helm) +(setq dumb-jump-prefer-searcher 'rg) + +;; projectile +(helm-projectile-on) +(setq projectile-project-search-path '("~/Development/")) diff --git a/emacs.d/default.el b/emacs.d/default.el new file mode 100644 index 0000000..0395a5d --- /dev/null +++ b/emacs.d/default.el @@ -0,0 +1,69 @@ +(require 'uniquify) + +(setq inhibit-splash-screen t) +(setq inhibit-startup-message t) +(setq frame-title-format "%F %b ") +(setq uniquify-buffer-name-style 'forward) + +(show-paren-mode) + + +(when (display-graphic-p) + (menu-bar-mode -1) + (tool-bar-mode -1) + (scroll-bar-mode -1)) +(display-graphic-p) + (menu-bar-mode -1) + (tool-bar-mode -1) + (scroll-bar-mode -1) + +(global-auto-revert-mode t) +(global-linum-mode) +(global-whitespace-mode) + +(put 'narrow-to-region 'disabled nil) +(put 'dired-find-alternate-file 'disabled nil) + +(setq gc-cons-threshold 20000000) +(setq make-backup-files nil) +(setq backup-directory-alist + `((".*" . ,temporary-file-directory))) +(setq auto-save-file-name-transforms + `((".*" ,temporary-file-directory t))) + +(setq vc-follow-symlinks t) +(setq confirm-kill-emacs 'y-or-n-p) +(setq ring-bell-function 'ignore) +(setq lazy-highlight-cleanup nil) +(setq whitespace-line-column 500) + +(setq-default indent-tabs-mode + nil) + +(fset 'yes-or-no-p 'y-or-n-p) + +(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. + '(default ((t (:height 120))))) + +;; ITERM2 MOUSE SUPPORT +(unless window-system + (require 'mouse) + (xterm-mouse-mode t) + (defun track-mouse (e)) + (setq mouse-sel-mode t) +) + + +(add-hook 'before-save-hook 'delete-trailing-whitespace) + +;;(desktop-save-mode t) + +(when (memq window-system '(mac ns x)) + (exec-path-from-shell-initialize)) +;;add path +(add-to-list 'exec-path "/usr/local/bin") +(add-to-list 'exec-path "~/.local/bin") diff --git a/emacs.d/helm.el b/emacs.d/helm.el new file mode 100644 index 0000000..196ae6e --- /dev/null +++ b/emacs.d/helm.el @@ -0,0 +1,9 @@ +;Set up helm-mode +(require 'helm) +(helm-mode 1) +(helm-autoresize-mode 1) + +(setq helm-split-window-in-side-p t) +(setq-default indent-tabs-mode nil) +(setq helm-grep-ag-command "rg --color=always --colors 'match:fg:black' --colors 'match:bg:yellow' --smart-case --no-heading --line-number %s %s %s") +(setq helm-grep-ag-pipe-cmd-switches '("--colors 'match:fg:black'" "--colors 'match:bg:yellow'")) diff --git a/emacs.d/init.el b/emacs.d/init.el new file mode 100644 index 0000000..b5cee6c --- /dev/null +++ b/emacs.d/init.el @@ -0,0 +1,42 @@ +;;; package --- Alain M. Lafon Emacs config +;;; Commentary: +;; - All of the configuration is within `configuration.org` +;;; Code: + +(package-initialize) + +;; This loads the actual configuration in literate org-mode elisp +(defun load-config() + (load-file "~/.emacs.d/default.el") + (load-file "~/.emacs.d/packages.el") + (load-file "~/.emacs.d/custom.el") + (load-file "~/.emacs.d/keyboard-bindings.el") + (load-file "~/.emacs.d/autocomplete.el") + (load-file "~/.emacs.d/python.el") + (load-file "~/.emacs.d/rust.el") + ;; (load-file "~/.emacs.d/lisp.el") + ) + + +(load-config) + +;;; init.el ends here + + +(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. + '(flycheck-checker-error-threshold 100000) + '(package-selected-packages + (quote + (js-format elpy csv-mode markdown-mode helm-rg dumb-jump writegood-mode crux rainbow-delimiters powerline py-autopep8 csharp-mode toml-mode importmagic exec-path-from-shell flycheck helm-projectile projectile company racer company-terraform terraform-mode json-mode jinja2-mode yaml-mode rust-mode magit material-theme neotree multiple-cursors helm))) + '(projectile-mode t nil (projectile))) +(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. + '(default ((t (:height 120))))) +(put 'upcase-region 'disabled nil) diff --git a/emacs.d/keyboard-bindings.el b/emacs.d/keyboard-bindings.el new file mode 100644 index 0000000..e303d43 --- /dev/null +++ b/emacs.d/keyboard-bindings.el @@ -0,0 +1,54 @@ +(defvar super-emacs--my-keyboard-bindings + '(("C-\," . neotree-toggle) + ("C-c M-x" . execute-extended-command) + ("M-x" . helm-M-x) + ("C-x b" . helm-mini) + ("C-x C-b" . helm-buffers-list) + ("C-x C-f" . helm-find-files) + ("C-x C-r" . helm-recentf) + ("C-c p h" . helm-projectile) + ("M-y" . helm-show-kill-ring) + ("C-S-" . buf-move-up) + ("C-S-" . buf-move-down) + ("C-S-" . buf-move-left) + ("C-S-" . buf-move-right) + ("C--" . undo) + ("C-x p" . previous-multiframe-window) + ("s--" . text-scale-decrease) + ("s-=" . text-scale-increase) + ("C-c m" . magit-status) + ("C-c g" . helm-projectile-grep) + ("C-S-s" . helm-occur) + ("C-c b" . helm-semantic-or-imenu) + ("C-c j" . helm-all-mark-rings) + ("C-a" . crux-move-beginning-of-line) + ("C-c g" . writegood-mode) + ("M-g o" . dumb-jump-go-other-window) + ("M-g j" . dumb-jump-go) + ("M-g q" .dump-jump-quick-look) + ("M-g i" . dumb-jump-go-prompt) + ("M-g x" . dumb-jump-go-prefer-external) + ("M-g z" . dumb-jump-go-prefer-external-other-window) + ("C-}" . mc/mark-next-like-this) + ("C-{" . mc/mark-previous-like-this) + ("C-|" . mc/mark-all-like-this) + ("" . super-emacs-reload-current-file) + )) + +(defun super-emacs-apply-keyboard-bindings (pair) + "Apply keyboard-bindings for supplied list of key-pair values" + (global-set-key (kbd (car pair)) + (cdr pair))) + +(mapc 'super-emacs-apply-keyboard-bindings + super-emacs--my-keyboard-bindings) + +(add-hook 'python-mode-hook (lambda () + (local-set-key (kbd "C-c i") (lambda () (interactive) ( + insert "import pdb; pdb.set_trace()"))))) +(defun super-emacs-reload-current-file () + "Reload the file loaded in current buffer from the disk" + (interactive) + (cond (buffer-file-name (progn (find-alternate-file buffer-file-name) + (message "File reloaded"))) + (t (message "You're not editing a file!")))) diff --git a/emacs.d/lisp.el b/emacs.d/lisp.el new file mode 100644 index 0000000..d766388 --- /dev/null +++ b/emacs.d/lisp.el @@ -0,0 +1,2 @@ +(setq lisp-body-indent 2) +(setq lisp-indent-offset 2) diff --git a/emacs.d/packages.el b/emacs.d/packages.el new file mode 100644 index 0000000..56b0b21 --- /dev/null +++ b/emacs.d/packages.el @@ -0,0 +1,43 @@ +;;; packages --- dependencies +;;; Commentary: + +;;; Code: +(require 'package) + +(setq package-archives '(("gnu" . "https://elpa.gnu.org/packages/") + ("marmalade" . "https://marmalade-repo.org/packages/") + ("melpa" . "https://melpa.org/packages/"))) +(defvar my-packages '( + company + company-terraform + crux + dumb-jump + elpy + exec-path-from-shell + flycheck + helm-projectile + importmagic + jinja2-mode + json-mode + magit + material-theme + multiple-cursors + neotree + powerline + projectile + racer + rainbow-delimiters + rust-mode + terraform-mode + toml-mode + writegood-mode + yaml-mode + helm + )) + +(dolist (p my-packages) + (unless (package-installed-p p) + (package-refresh-contents) + (package-install p)) + (add-to-list 'package-selected-packages p)) +;;; packages.el ends here diff --git a/emacs.d/python.el b/emacs.d/python.el new file mode 100644 index 0000000..c877857 --- /dev/null +++ b/emacs.d/python.el @@ -0,0 +1,11 @@ +(elpy-enable) +(setq elpy-rpc-python-command "/usr/local/Cellar/python3/3.7.3/bin/python3") +(setq python-shell-interpreter "/usr/local/Cellar/python3/3.7.3/bin/python3") +(setq flycheck-python-pycompile-executable "/usr/local/Cellar/python3/3.7.3/bin/python3") +(setq flycheck-python-flake8-executable "/usr/local/Cellar/python3/3.7.3/bin/python3") +(setq flycheck-python-pylint-executable "/usr/local/Cellar/python3/3.7.3/bin/python3") + +(when (require 'flycheck nil t) + (setq elpy-modules (delq 'elpy-module-flymake elpy-modules)) + (add-hook 'elpy-mode-hook 'flycheck-mode)) +(add-hook 'python-mode-hook 'importmagic-mode) diff --git a/emacs.d/rust.el b/emacs.d/rust.el new file mode 100644 index 0000000..4c94c99 --- /dev/null +++ b/emacs.d/rust.el @@ -0,0 +1,4 @@ +;Set up racer for rust-mode +(add-hook 'rust-mode-hook #'racer-mode) +(add-hook 'rust-mode-hook #'eldoc-mode) +(add-hook 'racer-mode-hook #'company-mode) diff --git a/emacs.d/tty-format.el b/emacs.d/tty-format.el new file mode 100644 index 0000000..cef0420 --- /dev/null +++ b/emacs.d/tty-format.el @@ -0,0 +1,507 @@ +;;; tty-format.el --- text file backspacing and ANSI SGR as faces + +;; Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2017 Kevin Ryde + +;; Author: Kevin Ryde +;; Version: 11 +;; Keywords: wp, faces, ansi +;; URL: http://user42.tuxfamily.org/tty-format/index.html +;; EmacsWiki: TtyFormat + +;; tty-format.el 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, or (at your option) any later +;; version. +;; +;; tty-format.el 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 can get a copy of the GNU General Public License online at +;; . + + +;;; Commentary: + +;; This is two additions to `format-alist' for decoding +;; +;; * ANSI SGR escape sequences "Esc [ ... m" colours, bold, underline, +;; etc through ansi-color.el. +;; +;; * Backspace overstriking for bold, underline, overline, and a bullet +;; "+ backspace o". +;; +;; Such sequences are tty or line printer oriented output, but are sometimes +;; found in text files. The aim is to make those files viewable and +;; hopefully have the attributes successfully copy into something like +;; `enriched-mode'. +;; +;; There's no automatic detection of these formats but you can "decode" a +;; buffer containing them with +;; +;; M-x format-decode-buffer backspace-overstrike +;; and/or +;; M-x format-decode-buffer ansi-colors +;; +;; `format-decode-buffer' has completion when it prompts for a format name. +;; +;; See `tty-format-guess' below for an idea to automatically notice text +;; files using these formats. +;; +;; Groff produces output like this (via grotty), and some of its manuals +;; have both ANSI and backspacing, as do various other packages with text +;; files produced from roff input. You might think backspacing by now would +;; be as long gone as the teletypes it was made for, but grotty still uses +;; it creatively. +;; +;; Groff actually has lots of character overstrike sequences to make ink +;; resembling non-ASCII characters. There's far too many to want in the +;; code here -- you're much better off asking groff for extended charset +;; output in the first place (utf8 or whatever), instead of decoding bizarre +;; combinations after the fact. So the aim here is only to handle bits +;; found in real life documents. One moderately frequent bit not yet +;; supported is | plus = for a footnote dagger. +;; +;; See also underline.el for a couple of simple functions adding or removing +;; backspace underlining. + +;;; Emacsen: + +;; Designed for Emacs 21 up. +;; Works in XEmacs 21 but maybe leaves buffer modified. +;; +;; Works in Emacs 20 if you have ansi-color.el. The separately published +;; ansi-color.el 3.4.5 works if you load cl.el for `mapc'. But note in +;; Emacs 20 faces don't display on a tty, only under X or similar GUI. + +;;; Install: + +;; To have M-x format-decode-buffer support the new formats put +;; tty-format.el in one of your `load-path' directories, and in your .emacs +;; add +;; +;; (require 'tty-format) +;; +;; If you want to try automatic detection on .txt files then add +;; +;; (add-hook 'find-file-hooks 'tty-format-guess) +;; +;; It's also possible to add the `format-alist' entries and then autoload +;; the functions so the code loads only when used. There's ;;;###autoload +;; cookies doing this if you install via `M-x package-install' or know how +;; to use `update-file-autoloads'. + +;;; History: + +;; Version 1 - the first version +;; Version 2 - call the format `ansi-colors' for clarity +;; Version 3 - add unicode U+203E overline +;; Version 4 - fix for re-matching multi-backspace sequences +;; Version 5 - autoload the format-alist additions, not whole file +;; Version 6 - autoload the encode too, for an unload-feature while in use +;; Version 7 - decimal char bytes for emacs20 +;; Version 8 - use ansi-color-apply-face-function when available +;; Version 9 - comments of explicit M-x format-decode-buffer +;; Version 10 - new email +;; Version 11 - compile-time decode-char for overline + +;;; Code: + +(require 'ansi-color) +(eval-when-compile + (unless (fboundp 'ignore-errors) + (require 'cl))) ;; for `ignore-errors' + +;;----------------------------------------------------------------------------- +;; compatibility + +;; not in xemacs, quieten its byte compiler +(defvar ansi-color-apply-face-function) + + +;;----------------------------------------------------------------------------- +;; faces + +;; As of Emacs 23.4 there's no builtin `overline' face, unlike say `bold' or +;; `underline', so define one here. It comes out nicely on X but dunno what +;; sort of fallback would be good on a tty. Usually overline is just groff +;; trying to draw a box, so if it doesn't display then it doesn't matter much. +;; +;; XEmacs 21 doesn't support :overline in defface and will throw an error on +;; attempting it. Known defface attributes are in 'custom-face-attributes', +;; which is pre-loaded in emacs but in xemacs21 must get it from +;; cus-face.el. defface uses `custom-define-face' from cus-face.el anyway, +;; so loading it doesn't drag in anything extra. +;; +(or (ignore-errors + ;; emacs21 and emacs22 + (defface tty-format-overline + '((t + (:overline t))) + "An overline face. +Used by buffer-format `backspace-overstrike' for overlining." + :group 'faces ;; in absense of our own group + :link '(url-link :tag "tty-format.el home page" + "http://user42.tuxfamily.org/tty-format/index.html")) + t) + + ;; xemacs21 + (defface tty-format-overline + '((t)) + "An overline face. +Used by buffer-format `backspace-overstrike' for overlining. + +It seems your Emacs doesn't support :overline, so the default +here is a is a do-nothing face." + :group 'faces ;; in absense of our own group + :link '(url-link :tag "tty-format.el home page" + "http://user42.tuxfamily.org/tty-format/index.html"))) + +(defun tty-format-add-faces (face-list beg end) + "Add FACE-LIST to the region between BEG and END. +FACE-LIST is a list of faces. These faces are merged onto any +existing `face' property by adding any of FACE-LIST not already +there. If no existing face property then FACE-LIST is stored as +the face property value. + +If it happens that some of the region already has all of +FACE-LIST then those parts are not changed at all. + +Faces are compared with `equal' so face names accumulate by name +even if some of them might look the same on screen." + + (when face-list + (while (< beg end) + (let ((part-end (next-single-property-change beg 'face nil end)) + (part-faces (get-text-property beg 'face))) + + (cond ((not part-faces) + ;; nothing currently, stick in our FACE-LIST directly + (setq part-faces face-list)) + + ((symbolp part-faces) + ;; single face symbol currently, merge with FACE-LIST + (if (memq part-faces face-list) + (setq part-faces face-list) + (setq part-faces (cons part-faces face-list)))) + + (t + ;; list of faces currently, adjoin FACE-LIST + (dolist (face face-list) + (unless (member face part-faces) + (setq part-faces (cons face part-faces)))))) + + ;; single symbol list -> symbol + (and (symbolp (car part-faces)) + (not (cdr part-faces)) + (setq part-faces (car part-faces))) + + (put-text-property beg part-end 'face part-faces) + (setq beg part-end))))) + + +;;----------------------------------------------------------------------------- +;; ansi sgr, via ansi-color.el + +;;;###autoload +(add-to-list 'format-alist + '(ansi-colors + "ANSI SGR escape sequence colours and fonts." + nil ;; no automatic detection + ansi-format-decode + ansi-format-encode + t + nil)) + +;;;###autoload +(defun ansi-format-encode (beg end buffer) + ;; checkdoc-params: (beg end buffer) + "Sorry, cannot encode `ansi-colors' format. +This function is designed for use in `format-alist'. + +There's no support for re-encoding to save a file in +`ansi-colors' format. (But of course you can copy into another +document with a format that does support saving.)" + (error "Sorry, `ansi-colors' format is read-only")) + +;;;###autoload +(defun ansi-format-decode (beg end) + "Decode ANSI SGR control sequences between BEG and END into faces. +This function is designed for use in `format-alist'. + +ANSI standard \"Esc [ ... m\" terminal control sequences are +turned into corresponding Emacs faces, using `ansi-colours'. + +There's no automatic detection of this format, because those +escape sequences could too easily occur in unrelated binary data. +Decode files with an explicit \\[format-decode-buffer], or see +`tty-format-guess' to try automated guessing on text files." + + (let ((inhibit-read-only t)) ;; if visiting a read-only file + (save-excursion + (save-restriction + (narrow-to-region beg end) + + ;; ansi-color.el of emacs24.3 up has + ;; `ansi-color-apply-face-function' which can be used to apply faces + ;; as properties instead of the default overlays. + (if (boundp 'ansi-color-apply-face-function) + (let ((ansi-color-apply-face-function + (lambda (beg end face) + (tty-format-add-faces (list face) beg end)))) + (setq ansi-color-context-region nil) + (ansi-color-apply-on-region (point-min) (point-max))) + + ;; For previous ansi-color.el, this is like + ;; `ansi-color-apply-on-region', but using text properties instead + ;; of overlays. And it's like `ansi-color-apply', but operating + ;; on a buffer instead of a string. Don't want to just put + ;; `buffer-string' through `ansi-color-apply' because that would + ;; lose marker positions, and also as of Emacs 22 + ;; `ansi-color-apply' is slow on big input due to a lot of string + ;; copying. + (goto-char (point-min)) + (let ((face-list nil) + (start (point-min)) + escape-sequence) + (while (re-search-forward ansi-color-regexp nil t) + (setq escape-sequence (match-string 1)) + (delete-region (match-beginning 0) (match-end 0)) + (tty-format-add-faces face-list start (point)) + (setq start (point)) + (setq face-list + (ansi-color-apply-sequence escape-sequence face-list))) + ;; remainder of buffer in final face + (tty-format-add-faces face-list start (point-max)))) + + (point-max))))) + + +;;----------------------------------------------------------------------------- +;; backspace overstrike + +;;;###autoload +(add-to-list 'format-alist + '(backspace-overstrike + "Backspace overstriking for bold and underline." + nil ;; no automatic detection + backspace-overstrike-decode + backspace-overstrike-encode + t + nil)) + +;;;###autoload +(defun backspace-overstrike-encode (beg end buffer) + ;; checkdoc-params: (beg end buffer) + "Sorry, cannot encode `backspace-overstrike' format. +This function is designed for use in `format-alist'. + +There's no support for re-encoding to save a file in +`backspace-overstrike' format. (But of course you can copy into +another document with a format that does support saving.)" + (error "Sorry, `backspace-overstrike' format is read-only")) + +;;;###autoload +(defun backspace-overstrike-decode (beg end) + "Decode backspace overstrike sequences between BEG and END into faces. +This function is designed for use in `format-alist'. + +The sequences recognised are: + + X backspace X -- bold + _ backspace X -- underline + U+203E backspace X -- overline (when unicode available) + + backspace o -- bullet point (latin-1 middle dot, + as per groff \\=\\[bu]]) + +Character overstriking like this was used in the past on line +printers and is still sometimes found in text files. + +There's no automatic detection of this format in `format-alist', +because backspace sequences could too easily occur in unrelated +binary data. Decode with an explicit \\[format-decode-buffer] or +see `tty-format-guess' to try automated guessing on text files." + + (let* ((inhibit-read-only t) ;; if visiting a read-only file + (case-fold-search nil) ;; don't match x\bX + + ;; string of U+203E overline character + (overline (or (eval-when-compile + (and (fboundp 'decode-char) ;; emacs21 up + (string (decode-char 'ucs 8254)))) + (and (memq 'utf-8 (coding-system-list)) + ;; xemacs21 doesn't have `coding-system-p' so use + ;; `coding-system-list', and it only has utf-8 + ;; anyway with mule-ucs + (decode-coding-string + (eval-when-compile + (let ((str (string 226 128 190))) + (if (fboundp 'string-make-unibyte) + (string-make-unibyte str) ;; emacs + str))) ;; xemacs + 'utf-8)))) + + (overline-regexp1 (and overline (concat overline "\b"))) + (overline-regexp2 (and overline (concat "[^\b]\\(\b[^\b_]\\)*?\\(\b" + overline "\\)"))) + (end-marker (make-marker)) + (face-idx 0)) + + (save-excursion + (save-restriction + (narrow-to-region beg end) + + ;; If you think the approach here looks overcomplicated, well, most + ;; of the time you'd be right. But the idea is to cope reasonably + ;; gracefully with backspacing that's only partly understood, + ;; ie. recognise and remove effects we know, and leave the rest as + ;; ^H's in the buffer. + ;; + ;; For speed it might be desirable to match simple runs of just bold + ;; or just underline, to avoid crunching and propertizing every + ;; character individually. But that can wait unless/until the + ;; general approach is not fast enough. + + (goto-char (point-min)) + (while (re-search-forward "[^\b]\b[^\b]\\(\b[^\b]\\)*" nil t) + ;; each run of backspacing + (goto-char (match-beginning 0)) + (set-marker end-marker (match-end 0)) + (setq face-idx 0) + + ;; The sequence "_\b_" is ambiguous: is it a bold underscore, or + ;; an underlined underscore? Both are probable, and groff gives + ;; that output for both requests. For now make it bold, since + ;; that's how it'd mostly look on a line printer. Thus crunch for + ;; bold before crunching underline. + ;; + ;; "+\bo" bullet can be boldened by doubling both the + and o, so + ;; also crunch bold before looking for that combination. + + ;; any duplicate chars in the run mean bold + (while (looking-at "\\([^\b]\b\\)*?\\([^\b]\\)\b\\([^\b]\b\\)*?\\2") + (delete-region (match-beginning 2) (+ 2 (match-beginning 2))) + (setq face-idx (logior face-idx 1))) + + ;; any "_" in the run means underline + (while (looking-at "_\b") + (delete-region (match-beginning 0) (match-end 0)) + (setq face-idx (logior face-idx 2))) + (while (looking-at "[^\b]\\(\b[^\b_]\\)*?\\(\b_\\)") + (delete-region (match-beginning 2) (match-end 2)) + (setq face-idx (logior face-idx 2))) + + ;; any unicode U+203E in the run means overline + (when overline + (while (looking-at overline-regexp1) + (delete-region (match-beginning 0) (match-end 0)) + (setq face-idx (logior face-idx 4))) + (while (looking-at overline-regexp2) + (delete-region (match-beginning 2) (match-end 2)) + (setq face-idx (logior face-idx 4)))) + + ;; "+" and "o" turns into latin1 #xB7 "middle dot". + ;; + ;; "+\bo" is what groff gives for bullet, and a middle dot in turn + ;; is what groff gives in latin1 (or utf8) output mode. Suspect a + ;; heavier mark like U+2022 would look better, but would want to + ;; be sure that's displayable. Also it might not degrade + ;; gracefully if copied to another buffer and saved into a + ;; non-unicode file. + ;; + (when (looking-at "\\([^\b]\b\\)*?\\(\\+\\)\\(\b[^\b]\\)*?\\(\bo\\)") + (let* ((opos (1- (match-end 0))) + (props (text-properties-at opos))) + ;; insert before delete to keep end-marker at the right spot + ;; xemacs21 `replace-match' doesn't take a subexpr, otherwise + ;; it might be used here + (save-excursion (goto-char opos) (insert "·")) + (set-text-properties opos (1+ opos) props) + (delete-region (1+ opos) (+ 2 opos)) ;; "o" + (delete-region (match-beginning 2) ;; "+\b" + (+ 2 (match-beginning 2))))) + (tty-format-add-faces (aref [nil + (bold) + (underline) + (bold underline) + (tty-format-overline) + (bold tty-format-overline) + (underline tty-format-overline) + (bold underline tty-format-overline)] + face-idx) + (point) (marker-position end-marker)) + (goto-char end-marker)) + + (set-marker end-marker nil) ;; nowhere + (point-max))))) + + +;;----------------------------------------------------------------------------- +;; text file guessing + +;;;###autoload +(defun tty-format-guess () + "Decode text files containing ANSI SGR or backspace sequences. +This is designed for use from `find-file-hook' (or +`find-file-hooks'). + +If the buffer filename is \".txt\" or \"README\" and there's any +ANSI SGR escapes or backspace overstriking then call +`format-decode-buffer' to decode with `ansi-colors' and/or +`backspace-overstrike' formats respectively. + +It'd be too dangerous to look at every file for escape and +backspace sequences, they could too easily occur in binary data +like an image file. The idea of this function is to check just +text files, presuming you're confident all \".txt\" files should +be ordinary text. + +If you normally use this guess but found it didn't notice then +remember the formats can always be decoded explicitly with + + \\[format-decode-buffer] backspace-overstrike +and/or + \\[format-decode-buffer] ansi-colors" + + (let ((filename (buffer-file-name))) + (when filename + (when (and (featurep 'jka-compr) + (jka-compr-installed-p)) + (setq filename (jka-compr-byte-compiler-base-file-name filename))) + + (when (let ((case-fold-search t)) + (or (string-match "\\.txt\\'" filename) + (string-match "/README\\'" filename))) + + (if (save-excursion + (goto-char (point-min)) + (re-search-forward "[^\b]\b[^\b]" nil t)) + (format-decode-buffer 'backspace-overstrike)) + + (if (save-excursion + (goto-char (point-min)) + (re-search-forward ansi-color-regexp nil t)) + (format-decode-buffer 'ansi-colors)))))) + +;; emacs 21 - find-file-hooks is a defvar +;; xemacs 21 - find-file-hooks is a defcustom, give custom-add-option +;; emacs 22 - find-file-hooks becomes an alias for find-file-hook, and the +;; latter is a defcustom, give custom-add-option on that +;; +;;;###autoload +(if (eval-when-compile (boundp 'find-file-hook)) + (custom-add-option 'find-file-hook 'tty-format-guess) ;; emacs22 + (custom-add-option 'find-file-hooks 'tty-format-guess)) ;; xemacs21 + + +;; LocalWords: Esc color overline overstrike overstriking groff Groff grotty +;; LocalWords: roff el tty unicode txt viewable charset + +;; Local variables: +;; coding: latin-1 +;; End: + +(provide 'tty-format) + +;;; tty-format.el ends here