diff --git a/custom.el b/custom.el index 0abbfb7..19886de 100644 --- a/custom.el +++ b/custom.el @@ -122,7 +122,11 @@ ("shell" . sh) ("bash" . sh))) '(package-selected-packages - '(syslog-mode + '(sed-mode + pacfiles-mode + company-nixos-options + nixos-options + syslog-mode google-c-style jinja2-mode masm-mode diff --git a/elpa/company-nixos-options-0.0.1/company-nixos-options-autoloads.el b/elpa/company-nixos-options-0.0.1/company-nixos-options-autoloads.el new file mode 100644 index 0000000..147a73e --- /dev/null +++ b/elpa/company-nixos-options-0.0.1/company-nixos-options-autoloads.el @@ -0,0 +1,28 @@ +;;; company-nixos-options-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "company-nixos-options" "company-nixos-options.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from company-nixos-options.el + +(autoload 'company-nixos-options "company-nixos-options" "\ + + +\(fn COMMAND &optional ARG &rest IGNORED)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "company-nixos-options" '("company-nixos-"))) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; company-nixos-options-autoloads.el ends here diff --git a/elpa/company-nixos-options-0.0.1/company-nixos-options-pkg.el b/elpa/company-nixos-options-0.0.1/company-nixos-options-pkg.el new file mode 100644 index 0000000..e3134d4 --- /dev/null +++ b/elpa/company-nixos-options-0.0.1/company-nixos-options-pkg.el @@ -0,0 +1,2 @@ +;;; Generated package description from company-nixos-options.el -*- no-byte-compile: t -*- +(define-package "company-nixos-options" "0.0.1" "Company Backend for nixos-options" '((company "0.8.0") (nixos-options "0.0.1") (cl-lib "0.5.0")) :commit "5fc8fa29bea9dd8e9c822af92f9bc6ddc223635f" :authors '(("Diego Berrocal" . "cestdiego@gmail.com") ("Travis B. Hartwell" . "nafai@travishartwell.net")) :maintainer '("Diego Berrocal" . "cestdiego@gmail.com") :keywords '("unix") :url "http://www.github.com/travisbhartwell/nix-emacs/") diff --git a/elpa/company-nixos-options-0.0.1/company-nixos-options.el b/elpa/company-nixos-options-0.0.1/company-nixos-options.el new file mode 100644 index 0000000..76815d0 --- /dev/null +++ b/elpa/company-nixos-options-0.0.1/company-nixos-options.el @@ -0,0 +1,90 @@ +;;; company-nixos-options.el --- Company Backend for nixos-options + +;; Copyright (C) 2015 Diego Berrocal and Travis B. Hartwell + +;; Author: Diego Berrocal +;; Travis B. Hartwell +;; Created: 18 July 2015 + +;; Keywords: unix +;; Package-Version: 0.0.1 +;; Package-Commit: 5fc8fa29bea9dd8e9c822af92f9bc6ddc223635f +;; Homepage: http://www.github.com/travisbhartwell/nix-emacs/ +;; Version: "0.1.0" +;; Package-Requires: ((company "0.8.0") (nixos-options "0.0.1") (cl-lib "0.5.0")) + +;; This file is not part of GNU Emacs. + +;;; License: GPLv3 + +;;; Commentary: + +;; Useful functions for exploring the NixOS options. Inspired by +;; https://nixos.org/nixos/options.html. + +;;; Code: +(require 'nixos-options) +(require 'company) +(require 'cl-lib) + +(defvar company-nixos-options-keywords + (mapcar (lambda (nixos-option) + (list (nixos-options-get-name nixos-option) + (nixos-options-get-description nixos-option))) + nixos-options)) + +(defun company-nixos-options--make-candidate (candidate) + (let* ((text (car candidate)) + (meta (cadr candidate))) + (propertize text 'meta meta))) + +;; The following two functions are borrowed from company-anaconda +(defun company-nixos-options--get-property (property candidate) + "Return the property PROPERTY of completion candidate CANDIDATE." + (let ((item (get-text-property 0 'item candidate))) + (plist-get item property))) + +(defun company-nixos-options--doc-buffer (candidate) + "Return documentation buffer for chosen CANDIDATE." + (let ((doc (nixos-options-get-documentation-for-option + (nixos-options-get-option-by-name candidate)))) + (and doc (nixos-options-doc-buffer doc)))) + +(defun company-nixos-options--candidates (prefix) + (let (res) + (dolist (item company-nixos-options-keywords) + (when (string-prefix-p prefix (car item)) + (push (company-nixos-options--make-candidate item) res))) + res)) + +(defun company-nixos-options--meta (candidate) + (format "This will use %s of %s" + (get-text-property 0 'meta candidate) + (substring-no-properties candidate))) + +(defun company-nixos-options--annotation (candidate) + (format " -> %s" (get-text-property 0 'meta candidate))) + +(defun company-nixos--grab-symbol () + (buffer-substring (point) (save-excursion (skip-syntax-backward "w_.") + (point)))) + +(defun company-nixos-options--prefix () + "Grab prefix at point." + (or (company-nixos--grab-symbol) + 'stop)) + +;;;###autoload +(defun company-nixos-options (command &optional arg &rest ignored) + (interactive (list 'interactive)) + (cl-case command + (interactive (company-begin-backend 'company-nixos-options)) + (prefix (company-nixos-options--prefix)) + (candidates (company-nixos-options--candidates arg)) + (doc-buffer (company-nixos-options--doc-buffer arg)) + ;; (annotation (company-nixos-options--annotation arg)) + (meta (company-nixos-options--meta arg)))) + +(provide 'company-nixos-options) + +;;; company-nixos-options.el ends here diff --git a/elpa/nixos-options-0.0.1/nixos-options-autoloads.el b/elpa/nixos-options-0.0.1/nixos-options-autoloads.el new file mode 100644 index 0000000..c7ea7a4 --- /dev/null +++ b/elpa/nixos-options-0.0.1/nixos-options-autoloads.el @@ -0,0 +1,22 @@ +;;; nixos-options-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "nixos-options" "nixos-options.el" (0 0 0 0)) +;;; Generated autoloads from nixos-options.el + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "nixos-options" '("define-nixos-options-item" "nixos-options"))) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; nixos-options-autoloads.el ends here diff --git a/elpa/nixos-options-0.0.1/nixos-options-pkg.el b/elpa/nixos-options-0.0.1/nixos-options-pkg.el new file mode 100644 index 0000000..0a3aa32 --- /dev/null +++ b/elpa/nixos-options-0.0.1/nixos-options-pkg.el @@ -0,0 +1,2 @@ +;;; Generated package description from nixos-options.el -*- no-byte-compile: t -*- +(define-package "nixos-options" "0.0.1" "Interface for browsing and completing NixOS options." '((emacs "24") (json "1.4")) :commit "5fc8fa29bea9dd8e9c822af92f9bc6ddc223635f" :authors '(("Diego Berrocal" . "cestdiego@gmail.com") ("Travis B. Hartwell" . "nafai@travishartwell.net")) :maintainer '("Diego Berrocal" . "cestdiego@gmail.com") :keywords '("unix") :url "http://www.github.com/travisbhartwell/nix-emacs/") diff --git a/elpa/nixos-options-0.0.1/nixos-options.el b/elpa/nixos-options-0.0.1/nixos-options.el new file mode 100644 index 0000000..f5a295f --- /dev/null +++ b/elpa/nixos-options-0.0.1/nixos-options.el @@ -0,0 +1,129 @@ +;;; nixos-options.el --- Interface for browsing and completing NixOS options. + +;; Copyright (C) 2015 Diego Berrocal and Travis B. Hartwell + +;; Author: Diego Berrocal +;; Travis B. Hartwell +;; Created: 18 July 2015 + +;; Keywords: unix +;; Package-Version: 0.0.1 +;; Package-Commit: 5fc8fa29bea9dd8e9c822af92f9bc6ddc223635f +;; Homepage: http://www.github.com/travisbhartwell/nix-emacs/ +;; Version: 0.0.1 +;; Package-Requires: ((emacs "24") (json "1.4")) + +;; This file is not part of GNU Emacs. + +;;; License: GPLv3 + +;;; Commentary: + +;; Useful functions for exploring the NixOS options. Inspired by +;; https://nixos.org/nixos/options.html. + +;;; Code: + +(require 'json) + +(defvar nixos-options-name-indent-amount 0 + "Indent by the maximum length, plus a colon, plus two spaces.") + +;; Macros for defining constants and functions for working with options +(defmacro define-nixos-options-item (item long-name) + (let* ((name-const (intern (concat "nixos-options-" item))) + (long-name-const (intern (concat "nixos-options-" item "-long-name"))) + (long-name-length-plus-padding (+ 3 (length long-name))) + (long-name-docstring (format "The long description for %s." item)) + (item-getter (intern (concat "nixos-options-get-" item))) + (item-getter-docstring + (format "Get the value of %s from OPTION." item)) + (item-display (intern (concat "nixos-options-display-" item))) + (item-display-docstring + (format "Display the value for %s from OPTION." item))) + `(progn + (defconst ,name-const ,item) + (defconst ,long-name-const ,long-name ,long-name-docstring) + (if (> ,long-name-length-plus-padding nixos-options-name-indent-amount) + (setq nixos-options-name-indent-amount + ,long-name-length-plus-padding)) + (defun ,item-getter (option) + ,item-getter-docstring + (cdr (assoc ,name-const option))) + (defun ,item-display (option) + ,item-display-docstring + (let ((item (,item-getter option)) + (format-string + (format "%%-%ds %%s\n" nixos-options-name-indent-amount))) + (if (not (null item)) + (format format-string (concat ,long-name-const ":") item) + "")))))) + +(define-nixos-options-item "name" "Name") +(define-nixos-options-item "type" "Type") +(define-nixos-options-item "description" "Description") +(define-nixos-options-item "default" "Default value") +(define-nixos-options-item "example" "Example value") +(define-nixos-options-item "declarations" "Declared in") + +(defvar nixos-options-json-file + (let* ((cmd + "nix-build --no-out-link '' -A options") + (dir (replace-regexp-in-string "\n\\'" "" + (shell-command-to-string cmd)))) + (expand-file-name "share/doc/nixos/options.json" dir)) + "Location of the options file.") + +(defun nixos-options--boolean-string (value) + "Return the string representation of the boolean VALUE. +Returns VALUE unchanged if not a boolean." + (cond ((eq value 't) "true") + ((eq value :json-false) "false") + (t value))) + +(defun nixos-options--make-alist (option) + (let ((name (car option)) + (data (cdr option)) + (default (nixos-options-get-default option)) + (example (nixos-options-get-example option))) + (progn + (if (not (null default)) + (setcdr (assoc nixos-options-default option) + (nixos-options--boolean-string default))) + (if (not (null example)) + (setcdr (assoc nixos-options-example option) + (nixos-options--boolean-string example))) + (add-to-list 'data `(,nixos-options-name . ,name)) + `(,name . ,data)))) + +(defvar nixos-options + (let* ((json-key-type 'string) + (raw-options (json-read-file nixos-options-json-file))) + (mapcar 'nixos-options--make-alist raw-options))) + +(defun nixos-options-get-documentation-for-option (option) + (concat (nixos-options-display-name option) + (nixos-options-display-type option) + (nixos-options-display-description option) + (nixos-options-display-default option) + (nixos-options-display-example option) + (nixos-options-display-declarations option))) + +;; Borrowed from anaconda-mode +(defun nixos-options-doc-buffer (doc) + "Display documentation buffer with contents DOC." + (let ((buf (get-buffer-create "*nixos-options-doc*"))) + (with-current-buffer buf + (view-mode -1) + (erase-buffer) + (insert doc) + (goto-char (point-min)) + (view-mode 1) + buf))) + +(defun nixos-options-get-option-by-name (name) + (assoc name nixos-options)) + +(provide 'nixos-options) + +;;; nixos-options.el ends here diff --git a/elpa/pacfiles-mode-1.0/pacfiles-buttons.el b/elpa/pacfiles-mode-1.0/pacfiles-buttons.el new file mode 100644 index 0000000..4d8c41c --- /dev/null +++ b/elpa/pacfiles-mode-1.0/pacfiles-buttons.el @@ -0,0 +1,232 @@ +;;; pacfiles-buttons.el --- the buttons of pacfiles-mode --- -*- lexical-binding: t; -*- + +;;; Commentary: +;; Definitions that deal with buttons and their fonts. +;; +;;; Code: + +(defgroup pacfiles-button-faces nil + "Faces for the buttons used in pacfiles-mode." + :group 'pacfiles) + +(defface pacfiles--apply-all + '((t (:inherit 'button :height 1.3))) + "Face for the Apply All button." + :group 'pacfiles-button-faces) + +(defface pacfiles--discard-all + '((t (:inherit 'button :height 1.3))) + "Face for the Apply All button." + :group 'pacfiles-button-faces) + +(defface pacfiles--discard + '((t (:inherit 'warning :weight bold :underline t))) + "Face for the Apply All button." + :group 'pacfiles-button-faces) + +(defface pacfiles--delete + '((t (:inherit 'error :weight bold :underline t))) + "Face for the Apply All button." + :group 'pacfiles-button-faces) + + +(define-button-type 'pacfiles--button-apply-all + 'face 'pacfiles--apply-all + 'follow-link t) + +(define-button-type 'pacfiles--button-discard-all + 'face 'pacfiles--discard-all + 'follow-link t) + +(define-button-type 'pacfiles--button-apply + 'face 'button + 'follow-link t) + +(define-button-type 'pacfiles--button-discard + 'face 'pacfiles--discard + 'follow-link t) + +(define-button-type 'pacfiles--button-delete + 'face 'pacfiles--delete + 'follow-link t) + +(define-button-type 'pacfiles--button-generic + 'face 'button + 'follow-link t) + + +(defvar pacfiles-activate-no-confirm nil + "Do not ask for user input when applying or discarding a merged file.") + +(defvar pacfiles--inhibit-button-revert nil + "Clicking a button does not revert the pacfiles list buffer.") + +(defun pacfiles--insert-merge-button (file-pair) + "Insert a button to merge FILE-PAIR. + +To determine the file-pair against which FILE will be merged, the extension of +FILE is removed." + (let* ((update-file (car file-pair)) + (base-file (file-name-sans-extension update-file))) + (if (file-exists-p base-file) + (progn + ;; Insert button that merges two files. + (insert-text-button "[merge]" + 'help-echo (format "Start merging '%s' and '%s'." + (file-name-nondirectory update-file) + (file-name-nondirectory base-file)) + 'action `(lambda (_) + (ediff-merge-files ,update-file ,base-file nil + ;; location of the merged file-pair + ,(cdr file-pair))) + 'type 'pacfiles--button-generic) + (insert " ")) + ;; The base file doesn't exist. + ;; Insert button that just copies the update to the merge file. + (insert-text-button "[merge]" + 'help-echo (format "Merge '%s'." + (file-name-nondirectory update-file)) + 'action `(lambda (_) + (when (y-or-n-p + (format "Base file '%s' not found. Use '%s' as is? " + ,base-file ,update-file)) + (copy-file ,update-file ,(cdr file-pair)) + (when (not pacfiles--inhibit-button-revert) (revert-buffer t t)))) + 'type 'pacfiles--button-generic) + (insert " ")))) + +(defun pacfiles--insert-view-merge-button (file-pair) + "Insert a button that displays the merge in FILE-PAIR." + (let* ((file-update (car file-pair)) + (file-base (file-name-sans-extension file-update)) + (file-merge (cdr file-pair))) + (insert-text-button "[view]" + 'help-echo (format "View the merge of '%s' with '%s'." + (file-name-nondirectory file-update) + (file-name-nondirectory file-base)) + 'action `(lambda (_) + (let ((window (split-window-right))) + (select-window window) + (set-window-buffer window + (pacfiles--create-view-buffer + (file-name-nondirectory ,file-base) ,file-merge)))) + 'type 'pacfiles--button-generic) + (insert " "))) + +(defun pacfiles--insert-diff-button (file-update) + "Insert a button that displays a diff of the update FILE-UPDATE and its base file." + (let ((file-base (file-name-sans-extension file-update))) + (if (file-exists-p file-base) + (progn + (insert-text-button "[diff]" + 'help-echo (format "Diff '%s' with '%s'." + (file-name-nondirectory file-update) + (file-name-nondirectory file-base)) + 'action `(lambda (_) (ediff-files ,file-update ,file-base)) + 'type 'pacfiles--button-generic) + (insert " ")) + ;; Replace the diff button with spaces + (insert " ")))) + +(defun pacfiles--insert-apply-button (file-pair) + "Insert a button that copies the `cdr' of FILE-PAIR to its `car'." + (let* ((merge-file (cdr file-pair)) + (update-file (car file-pair)) + (destination-file (file-name-sans-extension update-file))) + (insert-text-button "[apply]" + 'help-echo (format "Apply the merge of '%s' and '%s' to the file system." + (file-name-nondirectory update-file) + (file-name-sans-extension (file-name-nondirectory update-file))) + 'action `(lambda (_) + (when (or pacfiles-activate-no-confirm + (y-or-n-p (format "Apply the merge and overwrite '%s'? " + ,destination-file))) + ;; Copy and keep the destination file's permissions and user/group + (let* ((dst-file (pacfiles--add-sudo-maybe ,destination-file :write)) + (dst-attrs (file-attributes dst-file 'integer)) + (dst-uid (file-attribute-user-id dst-attrs)) + (dst-gid (file-attribute-group-id dst-attrs)) + (dst-mode (file-modes dst-file))) + (copy-file ,merge-file dst-file t) + (set-file-modes dst-file dst-mode) + (tramp-set-file-uid-gid dst-file dst-uid dst-gid)) + ;; Delete the merge and update files + (delete-file (pacfiles--add-sudo-maybe ,merge-file :write)) + (delete-file (pacfiles--add-sudo-maybe ,update-file :write)) + (when (not pacfiles--inhibit-button-revert) (revert-buffer t t)) + (message "Merge applied!"))) + 'type 'pacfiles--button-apply) + (insert " "))) + +(defun pacfiles--insert-discard-button (file-pair) + "Insert button that deletes the `cdr' of FILE-PAIR from the file system." + (let ((merge-file (cdr file-pair)) + (update-file (car file-pair))) + (insert-text-button "[discard]" + 'help-echo (format "Delete the merge of '%s' from the file system." + (file-name-sans-extension (file-name-nondirectory update-file))) + 'action `(lambda (_) + (let ((del-file (pacfiles--add-sudo-maybe ,merge-file :write))) + (when (or pacfiles-activate-no-confirm + (y-or-n-p (format "Discard the merge between '%s' and '%s'? " + ,update-file + ,(file-name-sans-extension update-file)))) + (delete-file del-file) + (message "Merge discarded!"))) + (when (not pacfiles--inhibit-button-revert) (revert-buffer t t))) + 'type 'pacfiles--button-discard) + (insert " "))) + +(defun pacfiles--insert-delete-button (file-pair) + "Insert a button that deletes the file in the `car' of FILE-PAIR." + (let ((update-file (car file-pair))) + (insert-text-button "[delete]" + 'help-echo (format "Delete '%s' from the file system." + (file-name-nondirectory update-file)) + 'action `(lambda (_) + (when (y-or-n-p (format "Delete '%s' permanently? " + ,update-file)) + (delete-file (pacfiles--add-sudo-maybe ,update-file :write)) + (message "File deleted!")) + (when (not pacfiles--inhibit-button-revert) (revert-buffer t t))) + 'type 'pacfiles--button-delete) + (insert " "))) + +(defun pacfiles--insert-footer-buttons () + "Insert the `apply all' and `discard all' buttons." + (insert-text-button "[Apply All]" + 'help-echo "Write all merged files into the system." + 'action (lambda (_) + (pacfiles--activate-all-buttons 'pacfiles--button-apply "apply")) + 'type 'pacfiles--button-apply-all) + (insert " ") + (insert-text-button "[Discard All]" + 'help-echo "Discard all merged files." + 'action (lambda (_) + (pacfiles--activate-all-buttons 'pacfiles--button-discard "discard")) + 'type 'pacfiles--button-discard-all)) + +(defun pacfiles--activate-all-buttons (activate-type action-name) + "Find all buttons with button type ACTIVATE-TYPE and activate them. +Use ACTION-NAME to display an appropriate warning message." + (when (y-or-n-p (concat (capitalize action-name) " all merged files? ")) + (save-excursion + (goto-char (point-min)) + ;; Catch errors that `forward-button' might throw. + (condition-case nil + (let* ((pacfiles-activate-no-confirm t) ; do not ask the user + (pacfiles--inhibit-button-revert t) + (button (forward-button 1 nil nil)) + (type (button-type button))) + ;; Iterate until we find the first footer button. + (while (not (eq type 'pacfiles--button-apply-all)) + (when (eq type activate-type) + (button-activate button)) + (setq button (forward-button 1 nil nil) + type (button-type button)))))) + (message "Done!") + (revert-buffer t t))) + + +(provide 'pacfiles-buttons) +;;; pacfiles-buttons.el ends here diff --git a/elpa/pacfiles-mode-1.0/pacfiles-mode-autoloads.el b/elpa/pacfiles-mode-1.0/pacfiles-mode-autoloads.el new file mode 100644 index 0000000..aed487d --- /dev/null +++ b/elpa/pacfiles-mode-1.0/pacfiles-mode-autoloads.el @@ -0,0 +1,62 @@ +;;; pacfiles-mode-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "pacfiles-buttons" "pacfiles-buttons.el" (0 +;;;;;; 0 0 0)) +;;; Generated autoloads from pacfiles-buttons.el + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "pacfiles-buttons" '("pacfiles-"))) + +;;;*** + +;;;### (autoloads nil "pacfiles-mode" "pacfiles-mode.el" (0 0 0 0)) +;;; Generated autoloads from pacfiles-mode.el + +(defalias 'pacfiles 'pacfiles-start) + +(autoload 'pacfiles-start "pacfiles-mode" "\ +Find and manage pacman backup files in an Arch-based GNU/Linux system." t nil) + +(autoload 'pacfiles-revert-buffer-no-confirm "pacfiles-mode" "\ +Revert the pacfiles list buffer without asking for confirmation." t nil) + +(autoload 'pacfiles-mode "pacfiles-mode" "\ + + +\(fn)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "pacfiles-mode" '("pacfiles-"))) + +;;;*** + +;;;### (autoloads nil "pacfiles-utils" "pacfiles-utils.el" (0 0 0 +;;;;;; 0)) +;;; Generated autoloads from pacfiles-utils.el + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "pacfiles-utils" '("pacfiles--"))) + +;;;*** + +;;;### (autoloads nil "pacfiles-win" "pacfiles-win.el" (0 0 0 0)) +;;; Generated autoloads from pacfiles-win.el + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "pacfiles-win" '("pacfiles-"))) + +;;;*** + +;;;### (autoloads nil nil ("pacfiles-mode-pkg.el") (0 0 0 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; pacfiles-mode-autoloads.el ends here diff --git a/elpa/pacfiles-mode-1.0/pacfiles-mode-pkg.el b/elpa/pacfiles-mode-1.0/pacfiles-mode-pkg.el new file mode 100644 index 0000000..14e911a --- /dev/null +++ b/elpa/pacfiles-mode-1.0/pacfiles-mode-pkg.el @@ -0,0 +1,13 @@ +(define-package "pacfiles-mode" "1.0" "pacnew and pacsave merging tool" + '((emacs "26") + (cl-lib "0.5")) + :commit "180eea7ba33dc4fa5c116b01649c4e9ba3f43276" :authors + '(("Carlos G. Cordero ")) + :maintainer + '("Carlos G. Cordero" . "pacfiles@binarycharly.com") + :keywords + '("files" "pacman" "arch" "pacnew" "pacsave" "update" "linux") + :url "https://github.com/UndeadKernel/pacfiles-mode") +;; Local Variables: +;; no-byte-compile: t +;; End: diff --git a/elpa/pacfiles-mode-1.0/pacfiles-mode.el b/elpa/pacfiles-mode-1.0/pacfiles-mode.el new file mode 100644 index 0000000..7e4ca4b --- /dev/null +++ b/elpa/pacfiles-mode-1.0/pacfiles-mode.el @@ -0,0 +1,270 @@ +;;; pacfiles-mode.el --- pacnew and pacsave merging tool -*- lexical-binding: t; -*- +;; +;; Copyright (C) 2018 Carlos G. Cordero +;; +;; Author: Carlos G. Cordero +;; Maintainer: Carlos G. Cordero +;; Created: Oct 11, 2018 +;; Modified: Oct 11, 2018 +;; Version: 1.0 +;; Keywords: files pacman arch pacnew pacsave update linux +;; URL: https://github.com/UndeadKernel/pacfiles-mode +;; Package-Requires: ((emacs "26") (cl-lib "0.5")) +;; +;; This file is not part of GNU Emacs. +;; +;;; Commentary: +;; +;; `pacfiles-mode' is an Emacs major mode to manage `.pacnew` and `.pacsave` +;; files left by Arch's pacman. To merge files, *pacfiles-mode* automatically +;; creates an Ediff merge session that a user can interact with. After finishing +;; the Ediff merge session, *pacfiles-mode* cleans up the mess that Ediff leaves +;; behind. *pacfiles-mode* also takes care of keeping the correct permissions of +;; merged files, and requests passwords (with TRAMP) to act as root when needed. +;; +;; Start the major mode using the command `pacfiles' or `pacfiles/start'. +;; +;;; Code: + +(require 'pacfiles-buttons) +(require 'pacfiles-utils) +(require 'pacfiles-win) + +(require 'cl-seq) +(require 'ediff) +(require 'outline) +(require 'time-date) + +(defgroup pacfiles nil "Faces for the buttons used in pacfiles-mode." + :group 'tools) + +(defvar pacfiles-updates-search-command "find /etc -name '*.pacnew' -o -name '*.pacsave' 2>/dev/null" + "Command to find .pacnew files.") + +(defvar pacfiles--merge-search-command + (concat "find " pacfiles-merge-file-tmp-location " -name '*.pacmerge' 2>/dev/null") + "Command to search for temporarily merged files.") + +(defvar pacfiles--ediff-conf '() + "Alist that stores ediff variables and its values.") + + +;;;###autoload +(defalias 'pacfiles 'pacfiles-start) + +;;;###autoload +(defun pacfiles-start () + "Find and manage pacman backup files in an Arch-based GNU/Linux system." + (interactive) + ;; Save the current window configuration so that it can be restored when we are finished. + (pacfiles--push-window-conf) + ;; Save ediff varaibles that we modify to later restore them to the uers's value. + (pacfiles--save-ediff-conf) + (let ((buffer (get-buffer-create pacfiles--files-buffer-name))) + (display-buffer buffer '(pacfiles--display-buffer-fullscreen)) + (with-current-buffer buffer + (pacfiles-mode) + (pacfiles-revert-buffer t t)))) + +(defun pacfiles-quit () + "Quit ‘pacfiles-mode’ and restore the previous window and ediff configuration." + (interactive) + (pacfiles--restore-ediff-conf) + ;; Kill buffers we create which start with '*pacfiles:' + (kill-matching-buffers "^\\*pacfiles:.*" t t) + (pacfiles--pop-window-conf)) + +;; Main function that displays the contents of the PACFILES buffer. +(defun pacfiles-revert-buffer (&optional _ignore-auto noconfirm) + "Populate the ‘pacfiles-mode’ buffer with .pacnew and .pacsave files. + +Ignore IGNORE-AUTO but take into account NOCONFIRM." + (interactive) + (with-current-buffer (get-buffer-create pacfiles--files-buffer-name) + (when (or noconfirm + (y-or-n-p (format "Reload list of backup pacman files? "))) + (run-hooks 'before-revert-hook) + ;; The actual revert mechanism starts here + (let ((inhibit-read-only t) + (files (split-string (shell-command-to-string pacfiles-updates-search-command) "\n" t)) + (merged-files (split-string (shell-command-to-string pacfiles--merge-search-command) "\n" t)) + (pacnew-alist (list)) + (pacsave-alist (list))) + (delete-region (point-min) (point-max)) + (insert "* PACFILES MODE" "\n") + ;; Split .pacnew and .pacsave files + (dolist (file files) + ;; Associate each FILE in FILES with a file to hold the merge + (let ((merge-file (pacfiles--calculate-merge-file file pacfiles-merge-file-tmp-location))) + (cond + ((string-match-p ".pacnew" file) + (push (cons file merge-file) pacnew-alist)) + ((string-match-p ".pacsave" file) + (push (cons file merge-file) pacsave-alist)) + (t (user-error (format "Cannot process file %s" file)))))) + ;; --- Process .pacnew files --- + (insert "\n\n" "** PACNEW files" "\n") + (insert "\n" "*** pending" "\n") + ;; Display the .pacnew files that need merging + (pacfiles--insert-pending-files pacnew-alist merged-files) + (insert "\n" "*** merged" "\n") + ;; Display .pacnew files that have an associated merge file. + (pacfiles--insert-merged-files pacnew-alist merged-files) + ;; --- Process .pacsave files --- + (insert "\n\n" "** PACSAVE files" "\n") + (insert "\n" "*** pending" "\n") + ;; Display the .pacsave files that need merging + (pacfiles--insert-pending-files pacsave-alist merged-files) + (insert "\n" "*** merged" "\n") + (pacfiles--insert-merged-files pacsave-alist merged-files) + (insert "\n\n") + (pacfiles--insert-footer-buttons)))) + (goto-char 0)) + +;;;###autoload +(defun pacfiles-revert-buffer-no-confirm () + "Revert the pacfiles list buffer without asking for confirmation." + (interactive) + (pacfiles-revert-buffer t t)) + +(defun pacfiles--insert-pending-files (files-alist merged-files) + "Insert files in FILES-ALIST if their `cdr' is not in MERGED-FILES. + +The FILE-TYPE specifies which type of update file we are processing." + ;; Keep files in FILES-ALIST which don't have a cdr in MERGED-FILES. + (let ((pending-alist (cl-remove-if (lambda (i) (member (cdr i) merged-files)) files-alist))) + (if (null pending-alist) + (insert (propertize "--- no pending files ---\n" 'font-lock-face 'font-lock-comment-face)) + (dolist (file-pair pending-alist) + (pacfiles--insert-merge-button file-pair) + (pacfiles--insert-diff-button (car file-pair)) + (pacfiles--insert-delete-button file-pair) + (insert (car file-pair) " ") + (pacfiles--insert-days-old (car file-pair)) + (insert "\n"))))) + +(defun pacfiles--insert-merged-files (files-alist merged-files) + "Insert files in FILES-ALIST that have an associated file in MERGED-FILES." + (let ((merged-alist (cl-remove-if-not (lambda (i) (member (cdr i) merged-files)) files-alist))) + (if (null merged-alist) + (insert (propertize "--- no merged files ---\n" 'font-lock-face 'font-lock-comment-face)) + (dolist (file-pair merged-alist) + (pacfiles--insert-apply-button file-pair) + (pacfiles--insert-view-merge-button file-pair) + (pacfiles--insert-discard-button file-pair) + (insert (car file-pair) " ") + ;; calculate how many days old is the merged file + (pacfiles--insert-days-created (cdr file-pair)) + (insert "\n"))))) + +(defun pacfiles--insert-days-old (file) + "Insert how many days passed between FILE and FILE without its extension. + +If REVERSE-ORDER is non-nil, calculate the time difference as +\(FILE without extension\) - FILE." + (let* ((base-file (file-name-sans-extension file)) + (time-base-file + (time-to-seconds (file-attribute-modification-time (file-attributes base-file)))) + (time-file + (time-to-seconds (file-attribute-modification-time (file-attributes file)))) + (reverse-time (< time-file time-base-file))) + (when (file-exists-p base-file) + (insert + (propertize + (format "(%.1f %s)" + (time-to-number-of-days + (cond (reverse-time (time-subtract time-base-file time-file)) + (t (time-subtract time-file time-base-file)))) + (if reverse-time "day[s] old" "day[s] ahead")) + 'font-lock-face 'font-lock-warning-face))))) + +(defun pacfiles--insert-days-created (file) + "Insert the number of days since FILE was created." + (if (file-exists-p file) + (let ((time-file (file-attribute-modification-time (file-attributes file)))) + (insert + (propertize + (format "(%.1f day[s] since created)" (time-to-number-of-days (time-since time-file))) + 'font-lock-face 'font-lock-string-face))) + (error "File '%s' dosn't exist" file))) + +(defun pacfiles--save-ediff-conf () + "Save ediff variables we modify with the user's current values. +We restore the saved variables after ‘pacfiles-mode’ quits." + (require 'ediff) + (let ((vars-to-save + '(ediff-autostore-merges ediff-keep-variants ediff-window-setup-function + ediff-before-setup-hook ediff-quit-hook ediff-cleanup-hook ediff-quit-merge-hook + ediff-quit-hook ediff-split-window-function))) + (dolist (var vars-to-save) + (push (pacfiles--var-to-cons var) pacfiles--ediff-conf)))) + +(defun pacfiles--change-ediff-conf () + "Change ediff's configuration variables to fit ‘pacfiles-mode’." + (setq ediff-autostore-merges nil + ediff-keep-variants t + ediff-window-setup-function #'ediff-setup-windows-plain + ediff-split-window-function #'split-window-horizontally) + (add-hook 'ediff-before-setup-hook #'pacfiles--push-window-conf) + (add-hook 'ediff-quit-hook #'pacfiles--pop-window-conf t) + (add-hook 'ediff-cleanup-hook #'pacfiles--clean-after-ediff) + (remove-hook 'ediff-quit-merge-hook #'ediff-maybe-save-and-delete-merge) + (add-hook 'ediff-quit-hook (lambda () (pacfiles-revert-buffer t t)))) + +(defun pacfiles--restore-ediff-conf () + "Restore the ediff variables saved by `pacfiles--save-ediff-conf'." + (dolist (pair pacfiles--ediff-conf) + (pacfiles--cons-to-var pair)) + (setq pacfiles--ediff-conf '())) + +(defvar pacfiles-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "q") #'pacfiles-quit) + (define-key map (kbd "g") #'pacfiles-revert-buffer-no-confirm) + (define-key map (kbd "r") #'pacfiles-revert-buffer-no-confirm) + (define-key map (kbd "TAB") #'outline-toggle-children) + (define-key map (kbd "C-c C-p") #'outline-previous-heading) + (define-key map (kbd "C-c C-n") #'outline-next-heading) + (define-key map (kbd "n") #'forward-button) + (define-key map (kbd "p") #'backward-button) + map) + "Keymap for ‘pacfiles-mode’.") + +;; Tell emacs that, when creating new buffers, pacfiles-mode should not be used +;; ... as the major mode. +(put 'pacfiles-mode 'mode-class 'special) + +;;;###autoload +(define-derived-mode pacfiles-mode outline-mode "pacfiles" + :syntax-table nil + :abbrev-table nil + "Major mode for managing .pacnew and .pacsave files." + ;; If the buffer is not the one we create, do nothing and error out. + (unless (string= (buffer-name) pacfiles--files-buffer-name) + (user-error "Use the command `pacfiles' instead of `pacfiles-mode' to start pacfiles-mode")) + ;; The buffer shall not be edited. + (read-only-mode) + ;; No edits... no undo. + (buffer-disable-undo) + ;; Disable showing parents locally by letting the mode think it's disabled. + (setq-local show-paren-mode nil) + (setq show-trailing-whitespace nil) + ;; Disable lines numbers. + (when (bound-and-true-p global-linum-mode) + (linum-mode -1)) + (when (and (fboundp 'nlinum-mode) + (bound-and-true-p global-nlinum-mode)) + (nlinum-mode -1)) + (when (and (fboundp 'display-line-numbers-mode) + (bound-and-true-p global-display-line-numbers-mode)) + (display-line-numbers-mode -1)) + ;; Set the function used when reverting pacfile-mode buffers. + (setq-local revert-buffer-function #'pacfiles-revert-buffer) + ;; configure ediff + (pacfiles--change-ediff-conf) + ;; configure outline-mode + (setq-local outline-blank-line t)) + + +(provide 'pacfiles-mode) +;;; pacfiles-mode.el ends here diff --git a/elpa/pacfiles-mode-1.0/pacfiles-utils.el b/elpa/pacfiles-mode-1.0/pacfiles-utils.el new file mode 100644 index 0000000..9197f8a --- /dev/null +++ b/elpa/pacfiles-mode-1.0/pacfiles-utils.el @@ -0,0 +1,36 @@ +;;; pacfiles-utils.el --- common utilities of pacfiles-mode -*- lexical-binding: t; -*- + +;;; Commentary: +;; Utility functions used throughout pacfiles-mode +;; +;;; Code: + +(defun pacfiles--calculate-merge-file (file path) + "File name associated to the merge file tied to FILE located in PATH." + (concat path (substring (secure-hash 'md5 file) 0 10) ".pacmerge")) + +(defun pacfiles--add-sudo-maybe (file-path permission) + "Add \"/sudo::\" to FILE-PATH if the file does not meet the PERMISSION. +FILE-PATH is a variable pointing to a file name. +PERMISSION is either \":read\" or \":write\"" + (let ((predicate (cond ((eq permission :read) #'file-readable-p) + ((eq permission :write) #'file-writable-p) + (t (user-error "Unknown keyword")))) + (apt-path file-path)) + (unless (funcall predicate apt-path) + (setq apt-path (concat "/sudo::" apt-path)) + (unless (funcall predicate apt-path) + (error "Could not %s \"%s\"" (if (eq permission :read) "read" "write") file-path))) + apt-path)) + +(defun pacfiles--var-to-cons (var) + "Create a cons of the VAR symbol and the VAR value." + `(,var . ,(symbol-value var))) + +(defun pacfiles--cons-to-var (cons) + "Set the `car' of CONS to the `cdr' of CONS." + (let ((var (car cons))) + (set var (cdr cons)))) + +(provide 'pacfiles-utils) +;;; pacfiles-utils.el ends here diff --git a/elpa/pacfiles-mode-1.0/pacfiles-win.el b/elpa/pacfiles-mode-1.0/pacfiles-win.el new file mode 100644 index 0000000..dcb3764 --- /dev/null +++ b/elpa/pacfiles-mode-1.0/pacfiles-win.el @@ -0,0 +1,84 @@ +;;; pacfiles-win.el --- Window related functions -*- lexical-binding: t; -*- + +;;; Commentary: +;; Functions to manage the windows of pacfiles-mode +;; +;;; Code: + +(require 'subr-x) +(require 'ediff) + +(defvar pacfiles--files-buffer-name "*pacfiles:file-list*" + "Name of the window that holds the list of pacman files.") + +(defvar pacfiles-merge-file-tmp-location "/tmp/" + "Location of temporary merged filed.") + +(defvar pacfiles--previous-window-confs '() + "The window configuration before `pacfiles' is called.") + +(defvar pacfiles--empty-buffer-name "*pacfiles:empty-buffer*" + "Empty buffer meant to replace buffers killed in EDIFF windows. +Doing this replacement avoids having multiple windows open with the same buffer. +Having the same buffer open in multiple windows might break the proper killing of +EDIFF windows.") + +(defun pacfiles--display-buffer-fullscreen (buffer alist) + "Display BUFFER fullscreen taking ALIST into account." + (when-let (window (or (display-buffer-reuse-window buffer alist) + (display-buffer-same-window buffer alist) + (display-buffer-pop-up-window buffer alist) + (display-buffer-use-some-window buffer alist))) + (delete-other-windows window) + window)) + +(defun pacfiles--push-window-conf () + "Push the current window configuration to later be restored by `pacfiles--restore-window-conf'." + (let ((win-conf (current-window-configuration))) + (push win-conf pacfiles--previous-window-confs))) + +(defun pacfiles--pop-window-conf () + "Restore the first window configuration found in `pacfiles--previous-window-confs'." + (if pacfiles--previous-window-confs + (condition-case nil + (progn + (let ((win-conf (pop pacfiles--previous-window-confs))) + (set-window-configuration win-conf))) + (error "Window configuration could not be restored")) + (error "No window configurations to restore"))) + +(defun pacfiles--clean-after-ediff () + "Kill buffers that ediff has left behind. Ask user if merged file is modified." + (let ((window-a ediff-window-A) + (window-b ediff-window-B) + (window-c ediff-window-C) + (empty-buffer (get-buffer-create pacfiles--empty-buffer-name))) + ;; Save the merged buffer if the user wants and kill it + (when window-c ; window-c is nil when diffing instead or merging + (save-excursion + (select-window window-c t) ; buffer-c is made current + (when (and (buffer-modified-p) + (y-or-n-p (format "'%s' was modified. Save before killing? " (buffer-name)))) + (save-buffer)) + (set-buffer-modified-p nil) ; Set buffer to not modified to not ask user + (kill-buffer) + (switch-to-buffer empty-buffer))) ;; Kill file-a and file-b always. We want to explicitly set the current buffer + ;; ... to make sure that no function in `kill-buffer-query-functions' stops us. + (save-excursion + (select-window window-a t) ; this makes buffer-a current + (switch-to-buffer empty-buffer)) + (save-excursion + (select-window window-b t) ; this makes buffer-b current + (switch-to-buffer empty-buffer)))) + +(defun pacfiles--create-view-buffer (name file) + "Show FILE in a new buffer named NAME that pacfiles will manage." + (let ((view-buffer + (get-buffer-create (concat "*pacfiles:merge-" name "*")))) + (with-current-buffer view-buffer + (insert-file-contents file nil nil nil t) + (read-only-mode) + view-buffer))) + +(provide 'pacfiles-win) +;;; pacfiles-win.el ends here diff --git a/elpa/sed-mode-1.0.signed b/elpa/sed-mode-1.0.signed new file mode 100644 index 0000000..655b34b --- /dev/null +++ b/elpa/sed-mode-1.0.signed @@ -0,0 +1 @@ +Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) (trust undefined) created at 2019-09-21T12:58:29-0500 using RSA \ No newline at end of file diff --git a/elpa/sed-mode-1.0/sed-mode-autoloads.el b/elpa/sed-mode-1.0/sed-mode-autoloads.el new file mode 100644 index 0000000..f2c47c9 --- /dev/null +++ b/elpa/sed-mode-1.0/sed-mode-autoloads.el @@ -0,0 +1,29 @@ +;;; sed-mode-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "sed-mode" "sed-mode.el" (0 0 0 0)) +;;; Generated autoloads from sed-mode.el + (add-to-list 'auto-mode-alist '("\\.sed\\'" . sed-mode)) + (add-to-list 'interpreter-mode-alist '("sed" . sed-mode)) + +(autoload 'sed-mode "sed-mode" "\ +Sed editing mode. + +\(fn)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "sed-mode" '("sed-"))) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; sed-mode-autoloads.el ends here diff --git a/elpa/sed-mode-1.0/sed-mode-pkg.el b/elpa/sed-mode-1.0/sed-mode-pkg.el new file mode 100644 index 0000000..fdecd04 --- /dev/null +++ b/elpa/sed-mode-1.0/sed-mode-pkg.el @@ -0,0 +1,2 @@ +;;; Generated package description from sed-mode.el -*- no-byte-compile: t -*- +(define-package "sed-mode" "1.0" "Major mode to edit sed scripts" 'nil :url "http://elpa.gnu.org/packages/sed-mode.html" :authors '(("Stefan Monnier" . "monnier@iro.umontreal.ca")) :maintainer '("Stefan Monnier" . "monnier@iro.umontreal.ca")) diff --git a/elpa/sed-mode-1.0/sed-mode.el b/elpa/sed-mode-1.0/sed-mode.el new file mode 100644 index 0000000..59234b8 --- /dev/null +++ b/elpa/sed-mode-1.0/sed-mode.el @@ -0,0 +1,154 @@ +;;; sed-mode.el --- Major mode to edit sed scripts -*- lexical-binding: t; -*- + +;; Copyright (C) 2016 Free Software Foundation, Inc. + +;; Author: Stefan Monnier +;; Version: 1.0 +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; If you need this major mode, you might also want to +;; consider spending some time with `M-x doctor'. + +;;; Code: + +(require 'cl-lib) +(require 'smie) + +(defgroup sed-mode nil + "Major mode to edit sed code." + :group 'programming) + + +(defvar sed-mode-syntax-table + (let ((st (make-syntax-table))) + (modify-syntax-entry ?# "<" st) + (modify-syntax-entry ?\n ">" st) + (modify-syntax-entry ?\\ "." st) + st)) + +(defconst sed-commands ":=aiqQrRbcdDhHgGlnNpPstTwWxy") + +(eval-and-compile + (defconst sed-command-prefix-regexp "\\(?:^\\|[$/0-9;]\\)[ \t]*") + (defconst sed-address-prefix-regexp "\\(?:^\\|[,;]\\)[ \t]*")) + +(defconst sed-label-regexp "[[:alnum:]]+") + +(defun sed-syntax-propertize (beg end) + (goto-char beg) + (sed-syntax-propertize-string end) + (funcall + (syntax-propertize-rules + ("\\\\$" + (0 (unless (nth 8 (save-excursion (syntax-ppss (match-beginning 0)))) + (put-text-property (match-beginning 0) (match-end 0) + 'syntax-table (string-to-syntax "|")) + (sed-syntax-propertize-string end) + nil))) + ((concat "\\(?:" sed-address-prefix-regexp + "\\(?:\\(?1:/\\)\\|\\\\\\(?1:.\\)\\)" + "\\|" sed-command-prefix-regexp "[sy]\\(?1:.\\)" + "\\)") + (0 (unless (nth 8 (save-excursion (syntax-ppss (match-beginning 0)))) + (put-text-property (match-beginning 1) (match-end 1) + 'syntax-table (string-to-syntax "\"")) + (sed-syntax-propertize-string end) + nil)))) + (point) end)) + +(defun sed-syntax-propertize-string (end) + (let* ((ppss (syntax-ppss)) + (c (nth 3 ppss))) + (when c + (let ((count (cond + ((or (eq c t) + (not (memq (char-before (nth 8 ppss)) '(?s ?y)))) + 1) + (t 2)))) + (goto-char (1+ (nth 8 ppss))) + (when (re-search-forward + (if (eq c t) "[^\\]\n" (regexp-quote (string c))) + end 'move count) + (put-text-property (1- (match-end 0)) (match-end 0) + 'syntax-table + (if (eq c t) (string-to-syntax "|") + (string-to-syntax "\"")))))))) + +(defun sed--font-lock-command (cmd) + (unless (nth 8 (syntax-ppss)) + (pcase cmd + (?: (if (looking-at (concat "[ ]*\\(" sed-label-regexp "\\)")) + (put-text-property (match-beginning 1) (match-end 1) 'face + font-lock-function-name-face))) + ((or ?b ?t ?T) + (if (looking-at (concat "[ ]*\\(" sed-label-regexp "\\)")) + (put-text-property (match-beginning 1) (match-end 1) 'face + font-lock-constant-face)))) + font-lock-keyword-face)) + +(defconst sed-font-lock-keywords + `((,(concat sed-command-prefix-regexp "\\([" sed-commands "]\\)") + (1 (sed--font-lock-command (char-after (match-beginning 1))))))) + +(defconst sed-smie-grammar nil) + +(defun sed-smie-rules (kind token) + (pcase (cons kind token) + (`(:list-intro . ,_) t) + )) + +;;;###autoload (add-to-list 'auto-mode-alist '("\\.sed\\'" . sed-mode)) +;;;###autoload (add-to-list 'interpreter-mode-alist '("sed" . sed-mode)) + +;;;###autoload +(define-derived-mode sed-mode prog-mode "Sed" + "Sed editing mode." + ;; (setq-local font-lock-support-mode nil) ;; To help debugging. + (setq-local comment-start "# ") + (setq-local comment-end "") + (setq-local parse-sexp-lookup-properties t) + (setq-local open-paren-in-column-0-is-defun-start nil) + (setq-local syntax-propertize-function #'sed-syntax-propertize) + (setq-local font-lock-defaults '(sed-font-lock-keywords)) + (smie-setup sed-smie-grammar #'sed-smie-rules + ;; :backward-token #'sm-c-smie-backward-token + ;; :forward-token #'sm-c-smie-forward-token + ) + ;; Backslash auto-realign. + ;; (add-hook 'after-change-functions #'sm-c--bs-after-change nil t) + ;; (add-hook 'post-command-hook #'sm-c--bs-realign nil t) + ;; (setq-local add-log-current-defun-header-regexp sm-c--def-regexp) + ;; (setq-local imenu-generic-expression `((nil ,sm-c--def-regexp 1))) + ) + +;;;; ChangeLog: + +;; 2016-02-26 Stefan Monnier +;; +;; * sed-mode/sed-mode.el: Bump up version for first release +;; +;; (interpreter-mode-alist): Register ourselves. +;; +;; 2016-02-25 Stefan Monnier +;; +;; * sed-mode: New package +;; + + +(provide 'sed-mode) +;;; sed-mode.el ends here