From 2d92526d2454c0865a0776023a84a6bdad04b640 Mon Sep 17 00:00:00 2001 From: John Doty Date: Mon, 12 Dec 2016 07:20:04 -0800 Subject: [PATCH] More emacs work. --- .config/NuGet/NuGet.Config | 3 + .emacs.d/core.el | 251 +++++++++++++++++++------------------ .emacs.d/custom.el | 16 ++- .emacs.d/init.el | 7 ++ .emacs.d/ox-quip.el | 20 +++ .emacs.d/quip.el | 100 ++++++++++++--- 6 files changed, 253 insertions(+), 144 deletions(-) diff --git a/.config/NuGet/NuGet.Config b/.config/NuGet/NuGet.Config index d0d4c10..bd1db53 100644 --- a/.config/NuGet/NuGet.Config +++ b/.config/NuGet/NuGet.Config @@ -3,4 +3,7 @@ + + + \ No newline at end of file diff --git a/.emacs.d/core.el b/.emacs.d/core.el index 2752e49..9e4b059 100644 --- a/.emacs.d/core.el +++ b/.emacs.d/core.el @@ -1,38 +1,39 @@ -;; ================================================================= -;; Filename: .emacs -;; Emacs initialization file -;; John Doty -;; -;; john@d0ty.me -;; ================================================================= - -;; This is my .emacs. -;; There are many like it, but this one is mine. -;; -;; (Well, it *was*.... but then I adopted starter-kit, because why not?) -;; -;; 2014/03/31 - Well, it isn't actually named .emacs anymore; but this is the -;; real initialization file, for code and junk. init.el just -;; does the package load stuff now. Don't know why package init -;; was built to work like it does in emacs 24, but oh well. -;; -;; Abandoning el-get for ELPA; ELPA seems more official and more -;; like what I want anyhow. Of course, this needs the -;; two-file-dance, but it's worth it. Much of the infrastructure -;; is based on starter-kit: -;; -;; https://github.com/eschulte/emacs24-starter-kit/blob/master/starter-kit.org -;; -;; 2014/03/21 - Started to re-work it based on https://github.com/dimitri/emacs-kicker/blob/master/init.el -;; -;; This emacs file has been around for a very long time, and it -;; has accumulated a lot of stuff. I'd like to try to clean it -;; up a little bit.... -;; -;; ...turns out that lots of the customization still makes -;; sense. But fetching the packages is still the hard part. -;; - +;;; core.el -- Summary +;;; Emacs initialization file +;;; john@d0ty.me +;;; +;;; Commentary: +;;; This is my .emacs. +;;; There are many like it, but this one is mine. +;;; +;;; 2016/12/03 - Just a note: been using Emacs far more heavily as my core +;;; editor @ FB for some reason. (They push a set of packages +;;; called Nuclide for the Atom editor, but I stopped using +;;; that.) +;;; +;;; 2014/03/31 - Well, it isn't actually named .emacs anymore; but this is +;;; the real initialization file, for code and junk. init.el +;;; just does the package load stuff now. Don't know why +;;; package init was built to work like it does in Emacs 24, but +;;; oh well. +;;; +;;; Abandoning el-get for ELPA; ELPA seems more official and +;;; more like what I want anyhow. Of course, this needs the +;;; two-file-dance, but it's worth it. Much of the +;;; infrastructure is based on starter-kit: +;;; +;;; https://github.com/eschulte/emacs24-starter-kit/blob/master/starter-kit.org +;;; +;;; 2014/03/21 - Started to re-work it based on https://github.com/dimitri/emacs-kicker/blob/master/init.el +;;; +;;; This Emacs file has been around for a very long time, and it +;;; has accumulated a lot of stuff. I'd like to try to clean it +;;; up a little bit.... +;;; +;;; ...turns out that lots of the customization still makes +;;; sense. But fetching the packages is still the hard part. +;;; +;;; Code: ;; ================================================================= ;; First, before anything... server goop. ;; ================================================================= @@ -88,13 +89,10 @@ ;; Packages ;; ================================================================= (setq package-archives - '( - ("gnu" . "http://elpa.gnu.org/packages/") + '(("gnu" . "http://elpa.gnu.org/packages/") ("org" . "http://orgmode.org/elpa/") ("melpa" . "http://melpa.org/packages/") - ;("marmalade" . "http://marmalade-repo.org/packages/") - ) - ) + ("marmalade" . "https://marmalade-repo.org/packages/"))) (when (< emacs-major-version 24) ;; For important compatibility libraries like cl-lib (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/"))) @@ -102,34 +100,30 @@ (defvar my-packages (list - 'switch-window ; takes over C-x o 'auto-complete ; complete as you type with overlays - 'zencoding-mode ; http://www.emacswiki.org/emacs/ZenCoding - 'ruby-mode ; Major mode for editing Ruby files + 'auto-complete-nxml ; Auto-complete for nxml 'color-theme ; Color themes... + 'color-theme-monokai ; ...Monokai 'color-theme-solarized ; ...Solarized 'csharp-mode ; C# mode - 'js2-mode ; Improved JS mode - 'lua-mode ; LUA - 'go-mode ; Go programming language mode - 'flyspell ; Spell-checking - - 'flymake ; Compiling - 'flycheck ; Checking - 'exec-path-from-shell ; Fix path on MacOS - + 'flycheck ; Checking + 'flymake ; Compiling + 'flyspell ; Spell-checking 'go-autocomplete ; Autocomplete for golang + 'go-mode ; Go programming language mode + 'js2-mode ; Improved JS mode + 'json-mode ; JSON mode + 'lua-mode ; LUA + 'magit ; Magit! SO GOOD. + 'paredit ; Also good for lisps. 'popup ; Pretty completions? - 'python-mode ; Python - + 'ruby-mode ; Major mode for editing Ruby files + 'switch-window ; takes over C-x o 'tss ; Typescript, ala https://github.com/aki2o/emacs-tss - - 'paredit ; Also good for lisps? - - 'auto-complete-nxml ; Auto-complete for nxml (maybe?) - 'magit ; Magit? + 'web-mode ; Mixed mode web editing + 'zencoding-mode ; http://www.emacswiki.org/emacs/ZenCoding ) "Libraries that should be installed by default.") @@ -176,7 +170,6 @@ (blink-cursor-mode 0) ;; No tool bars! No menu bars! I don't use that stuff anyway. -;; (if (fboundp 'tool-bar-mode) (tool-bar-mode -1)) (if (fboundp 'menu-bar-mode) (menu-bar-mode -1)) @@ -231,13 +224,7 @@ (setq initial-frame-alist `((font . ,my-font-choice) (width . 91) - (height . ,jd-frame-height))) - - ;; COLORZ! - ;; - (require 'color-theme) - (require 'color-theme-solarized) - (color-theme-solarized))) + (height . ,jd-frame-height))))) ;; ================================================================= ;; FUN WITH KEY BINDINGS! YAAAAYYY!!! @@ -328,17 +315,7 @@ (flyspell-prog-mode) (define-key c-mode-base-map "\C-m" 'c-context-line-break) (set-fill-column 120) - (local-set-key "}" 'indent-on-closing-bracket) - - ; Handle super-tabbify (ctrl-' expands; my fingers are to used to TAB doing - ; the right thing in emacs for me to change at this point. - (setq dabbrev-case-replace t) - (setq dabbrev-case-fold-search t) - (setq dabbrev-upcase-means-case-search t) - - ; Abbrevation expansion - (abbrev-mode 1) - (define-key c-mode-base-map [(control ?')] 'dabbrev-expand)) + (local-set-key "}" 'indent-on-closing-bracket)) (add-hook 'c-mode-common-hook 'my-c-common-hook) @@ -370,7 +347,7 @@ (add-to-list 'auto-mode-alist '("\\.w\\'" . c++-mode)) (defun my-makefile-hook () - (setq-local indent-tabs-mode t) ;; Makefiles haven't needed tabs for a long time. + (setq-local indent-tabs-mode nil) ;; Makefiles haven't needed tabs for a long time. ) (add-hook 'makefile-mode-hook 'my-makefile-hook) @@ -607,6 +584,50 @@ (add-hook 'nxml-mode-hook 'my-nxml-hook) +;; ================================================================= +;; Flycheck +;; ================================================================= +(require 'flycheck) +;; disable jshint since we prefer eslint checking +(setq-default flycheck-disabled-checkers + (append flycheck-disabled-checkers + '(javascript-jshint))) + +;; use eslint with web-mode for jsx files +(flycheck-add-mode 'javascript-eslint 'web-mode) + +;; customize flycheck temp file prefix +(setq-default flycheck-temp-prefix ".flycheck") + +;; disable json-jsonlist checking for json files +(setq-default flycheck-disabled-checkers + (append flycheck-disabled-checkers + '(json-jsonlist))) + +(flycheck-define-checker python-fb-flake8 + "A Python syntax and style checker using FB's Flake8." + :command ("flake8") + :standard-input nil + :error-filter (lambda (errors) + (let ((errors (flycheck-sanitize-errors errors))) + (seq-do #'flycheck-flake8-fix-error-level errors) + errors)) + :error-patterns + ((warning line-start + "stdin:" line ":" (optional column ":") " " + (id (one-or-more (any alpha)) (one-or-more digit)) " " + (message (one-or-more not-newline)) + line-end)) + :modes python-mode) + +(when is-fb-environment + (add-hook 'python-mode-hook + (lambda () + (flycheck-select-checker `python-fb-flake8))) + ) + +(global-flycheck-mode) + ;; ================================================================= ;; Python Support ;; ================================================================= @@ -617,17 +638,12 @@ (setq interpreter-mode-alist (cons '("python" . python-mode) interpreter-mode-alist)) -(defun my-python-hook () - (flycheck-mode) - ) - -(add-hook 'python-mode-hook 'my-python-hook) - ;; ================================================================= ;; JavaScript Support ;; ================================================================= (autoload 'js2-mode "js2-mode" nil t) (add-to-list 'auto-mode-alist '("\\.js$" . js2-mode)) +(add-to-list 'auto-mode-alist '("\\.jsx$" . web-mode)) ;; ================================================================= ;; Ruby Mode @@ -655,15 +671,6 @@ (add-to-list 'auto-mode-alist '("\\.lua$" . lua-mode)) (add-to-list 'interpreter-mode-alist '("lua" . lua-mode)) -;; ================================================================= -;; Source Depot -;; ================================================================= -;; (load-library "sd") -;; (setq sd-use-sdconfig-exclusively t) -;; (sd-set-sd-executable "c:/tools/x86/sd.exe") -;; (setq sd-global-config "sd.ini") -;; (setenv "SDCONFIG" "sd.ini") - ;; ================================================================= ;; Code Folding ;; ================================================================= @@ -681,6 +688,7 @@ (add-hook 'sh-mode-hook 'hs-minor-mode) (defun display-code-line-counts (ov) + "Put the line counts in the fold overlay OV." (when (eq 'code (overlay-get ov 'hs)) (overlay-put ov 'help-echo (buffer-substring (overlay-start ov) @@ -697,7 +705,7 @@ (require 'go-autocomplete) (defun my-go-mode-hook () - (flycheck-mode) + "My go-mode hook." (auto-complete-mode) ) @@ -756,13 +764,13 @@ (find-project-directory-recursive))) (defun lock-compilation-directory () - "The compilation process should NOT hunt for a makefile" + "The compilation process should NOT hunt for a makefile." (interactive) (setq compilation-directory-locked t) (message "Compilation directory is locked.")) (defun unlock-compilation-directory () - "The compilation process SHOULD hunt for a makefile" + "The compilation process SHOULD hunt for a makefile." (interactive) (setq compilation-directory-locked nil) (message "Compilation directory is roaming.")) @@ -785,7 +793,7 @@ (define-key global-map "\C-c\C-m" 'make-without-asking) (defun set-vs-environment () - "Load the VS environment variables into the current emacs process." + "Load the VS environment variables into the current Emacs process." (interactive) (dolist (ev (split-string @@ -794,8 +802,8 @@ (letrec ((spev (split-string ev "=")) (vn (car spev)) (vv (cadr spev))) - (setenv vn vv))) - (message "Set visual studio environment variables")) + (setenv vn vv)))) + ;; ================================================================= ;; PHP stuff @@ -814,27 +822,26 @@ (add-hook 'php-mode-hook 'my-fb-php-hook) )) -(if is-fb-environment - (progn - (flycheck-define-checker python-fb-flake8 - "A Python syntax and style checker using FB's Flake8." - :command ("flake8") - :standard-input f - :error-filter (lambda (errors) - (let ((errors (flycheck-sanitize-errors errors))) - (seq-do #'flycheck-flake8-fix-error-level errors) - errors)) - :error-patterns - ((warning line-start - "stdin:" line ":" (optional column ":") " " - (id (one-or-more (any alpha)) (one-or-more digit)) " " - (message (one-or-more not-newline)) - line-end)) - :modes python-mode) +;; ================================================================= +;; Magit stuff +;; ================================================================= - (add-hook 'python-mode-hook - (lambda () - (flycheck-select-checker `python-fb-flake8) - )) - )) +(global-set-key (kbd "C-x g") 'magit-status) + +;; ================================================================= +;; Shell stuff +;; ================================================================= + +(setenv "PAGER" "cat") +(setenv "EDITOR" "emacsclient") +(add-hook 'comint-output-filter-functions 'comint-truncate-buffer) +(add-hook 'shell-mode-hook 'buffer-disable-undo) + +;; +;; Comment all the time +;; +(global-set-key (kbd "C-/") 'comment-or-uncomment-region) + +(provide 'core) +;;; core.el ends here diff --git a/.emacs.d/custom.el b/.emacs.d/custom.el index 0994754..fc4d13f 100644 --- a/.emacs.d/custom.el +++ b/.emacs.d/custom.el @@ -4,10 +4,14 @@ ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. '(blink-matching-paren-dont-ignore-comments t) + '(c-basic-offset 2) '(c-echo-syntactic-information-p t) '(c-indent-level 4) '(c-label-minimum-indentation 0) '(c-label-offset -4) + '(comint-input-ignoredups t) + '(comint-prompt-read-only t) + '(comint-scroll-to-bottom-on-input t) '(css-indent-offset 2) '(fast-lock-cache-directories (quote ("~/flc-cache"))) '(fast-lock-minimum-size nil) @@ -23,20 +27,22 @@ '(indent-tabs-mode nil) '(inhibit-startup-screen t) '(ispell-program-name "aspell") + '(js-indent-level 2) '(js2-basic-offset 2) '(js2-bounce-indent-p t) '(js2-strict-trailing-comma-warning nil) '(make-backup-files nil) '(mouse-buffer-menu-mode-mult 0) - '(org-export-backends (quote (ascii html icalendar latex md))) '(org-hide-leading-stars t) '(org-odd-levels-only t) - '(quip-api-key - "UU9RQU1BcTNCdU0=|1506626374|H13gPE9bkDAkHQp9PtTlX8i78wYvtSBwEJgLAuChnXs=") + '(package-selected-packages + (quote + (dockerfile-mode js2-mode ## web-mode ahg zencoding-mode tss switch-window python-mode paredit monky magit lua-mode go-mode go-autocomplete flycheck exec-path-from-shell csharp-mode color-theme-solarized color-theme-monokai auto-complete-nxml))) '(rmail-mail-new-frame t) '(safe-local-variable-values (quote - ((eval ignore-errors "Write-contents-functions is a buffer-local alternative to before-save-hook" + ((docker-image-name . "onceandfuture") + (eval ignore-errors "Write-contents-functions is a buffer-local alternative to before-save-hook" (add-hook (quote write-contents-functions) (lambda nil @@ -56,7 +62,6 @@ '(sd-verbose nil) '(show-paren-mode t) '(show-paren-style (quote parenthesis)) - '(solarized-termcolors 256) '(tab-width 4) '(tags-revert-without-query t) '(transient-mark-mode t) @@ -64,7 +69,6 @@ '(use-dialog-box nil) '(web-mode-code-indent-offset 2) '(web-mode-css-indent-offset 2) - '(web-mode-enable-sql-detection t) '(which-func-mode-global t nil (which-func)) '(widget-editable-list-gui t) '(x-stretch-cursor nil)) diff --git a/.emacs.d/init.el b/.emacs.d/init.el index 1c37f58..a6c088c 100644 --- a/.emacs.d/init.el +++ b/.emacs.d/init.el @@ -6,6 +6,13 @@ ;; ;; load Org-mode from source when the ORG_HOME environment variable is set + +;; Added by Package.el. This must come before configurations of +;; installed packages. Don't delete this line. If you don't want it, +;; just comment it out by adding a semicolon to the start of the line. +;; You may delete these explanatory comments. +(package-initialize) + (when (getenv "ORG_HOME") (let ((org-lisp-dir (expand-file-name "lisp" (getenv "ORG_HOME")))) (when (file-directory-p org-lisp-dir) diff --git a/.emacs.d/ox-quip.el b/.emacs.d/ox-quip.el index 09c88ed..6ab6303 100644 --- a/.emacs.d/ox-quip.el +++ b/.emacs.d/ox-quip.el @@ -29,4 +29,24 @@ (let ((new-quip-id (org-quip-publish-quip content))) (org-quip-put-thread-identifier new-quip-id))))) +;; + +;; Org-to-quip filter: +;; +;; So, Quip HTML is a very specific, strict subset of HTML. Quip has only a +;; few different block types, and it can't do certain things (like +;; multi-paragraph list items.) +;; +;; Structure: +;; - A list of top-level items: +;; +;; Headlines:

+;; Block quotes:
+;; Code block:
+;;
+;;    

+;; +;; + + (provide 'ox-quip) diff --git a/.emacs.d/quip.el b/.emacs.d/quip.el index 8969358..716db84 100644 --- a/.emacs.d/quip.el +++ b/.emacs.d/quip.el @@ -15,8 +15,8 @@ (defun quip-invoke-json (path method params) "Submit a request to the Quip API. Returns the parsed JSON from the response." (if (not quip-api-key) - (error "The custom variable quip-api-key is undefined. -Use custom-set-variable to set it before using quip.")) + (error "%s" + "The custom variable quip-api-key is undefined. Use custom-set-variable to set it before using quip.")) (let ((url (concat "https://platform.quip.com/1/" path)) (url-request-method method) @@ -31,11 +31,11 @@ Use custom-set-variable to set it before using quip.")) (re-search-forward "^$") (json-read)))) -(defun quip-new-document (content) +(defun quip-new-document (content &optional format) "Create a new Quip document with the provided content. Returns the parsed JSON response." (quip-invoke-json "threads/new-document" "POST" - `((format . "markdown") + `((format . ,(or format "markdown")) (content . ,content)))) (defun quip-get-thread (id) @@ -49,62 +49,130 @@ Use custom-set-variable to set it before using quip.")) (defconst quip-location-replace-section 4) (defconst quip-location-delete-section 5) -(defun quip-thread-append (thread content) +(defun quip-thread-append (thread content &optional format) "Append the content to the specified thread." (quip-invoke-json "threads/edit-document" "POST" - `((format . "markdown") + `((format . ,(or format "markdown")) (content . ,content) (location . ,quip-location-append) (thread_id . ,thread)))) -(defun quip-thread-prepend (thread content) +(defun quip-thread-prepend (thread content &optional format) "Prepend the content to the specified thread." (quip-invoke-json "threads/edit-document" "POST" - `((format . "markdown") + `((format . ,(or format "markdown")) (content . ,content) (location . ,quip-location-prepend) (thread_id . ,thread)))) -(defun quip-thread-append-after (thread section content) +(defun quip-thread-append-after (thread section content &optional format) "Append the content to the specified thread after the specified section." (quip-invoke-json "threads/edit-document" "POST" - `((format . "markdown") + `((format . ,(or format "markdown")) (content . ,content) (location . ,quip-location-append-section) (section_id . ,section) (thread_id . ,thread)))) -(defun quip-thread-prepend-before (thread section content) +(defun quip-thread-prepend-before (thread section content &optional format) "Prepend the content to the specified thread before the specified section." (quip-invoke-json "threads/edit-document" "POST" - `((format . "markdown") + `((format . ,(or format "markdown")) (content . ,content) (location . ,quip-location-prepend-section) (section_id . ,section) (thread_id . ,thread)))) -(defun quip-thread-replace-section (thread section content) +(defun quip-thread-replace-section (thread section content &optional format) "Replace the content of the specified section." (quip-invoke-json "threads/edit-document" "POST" - `((format . "markdown") + `((format . ,(or format "markdown")) (content . ,content) (location . ,quip-location-replace-section) (section_id . ,section) (thread_id . ,thread)))) -(defun quip-thread-delete-section (thread section) +(defun quip-thread-delete-section (thread section &optional format) "Delete the specified section." (quip-invoke-json "threads/edit-document" "POST" - `((format . "markdown") + `((format . ,(or format "markdown")) (content . ,content) (location . ,quip-location-delete-section) (section_id . ,section) (thread_id . ,thread)))) + +;;; Content parsing functions + +(defun quip-get-item-type (item) + (let ((elem-type (car item)) + (attribs (cadr item))) + (cond + ((eq elem-type 'p) 'paragraph) + ((eq elem-type 'h1) 'h1) + ((eq elem-type 'h2) 'h2) + ((eq elem-type 'h3) 'h3) + ((eq elem-type 'blockquote) 'block-quote) + ((eq elem-type 'q) 'pull-quote) + ((eq elem-type 'pre) 'code-block) + ((eq elem-type 'li) 'list-item) + ((eq elem-type 'span) 'span) + ((eq elem-type 'div) + (letrec ((style (assoc-default 'data-section-style attribs)) + (inner (caddr item)) + (inner-elem-type (car inner))) + (cond + ((eq inner-elem-type 'ul) 'ul) + ((eq inner-elem-type 'ol) 'ol) + (t 'unrecognized-inner)))) + (t 'unrecognized)))) + +(defun quip-get-item-id (type item) + (let ((attribs (cadr item))) + (cond + ((or (eq type 'ul) ;; Nested IDs. + (eq type 'ol)) + (letrec ((inner (caddr item)) + (inner-attribs (cadr inner))) + (assoc-default 'id inner-attribs))) + (t (assoc-default 'id attribs))))) + +(defun quip-get-item-content (type item) + (cond + ((or (eq type 'ul) ;; Nested Content + (eq type 'ol)) + (letrec ((inner (caddr item)) + (inner-elems (cddr inner))) + (mapcar #'quip-get-item-from-element inner-elems))) + (t (caddr item)))) + +(defun quip-get-item-from-element (element) + (letrec + ((item-type (quip-get-item-type element)) + (item-id (quip-get-item-id item-type element)) + (item-content (quip-get-item-content item-type element))) + `(,item-type ,item-id ,item-content))) + + +(defun quip-parse-html-content (content) + (with-temp-buffer + (insert content) + (letrec + ((html (libxml-parse-html-region (point-min) (point-max))) + (raw-items (cddr (caddr html))) + (html-items (remove-if #'stringp raw-items))) + + (mapcar #'quip-get-item-from-element html-items) + ))) + +;; (prin1 +;; (quip-parse-html-content +;; (assoc-default 'html (quip-get-thread "idflAWG6R6Uu")))) + (provide 'quip-api)