aboutsummaryrefslogtreecommitdiff
path: root/sx.el
diff options
context:
space:
mode:
authorJonathan Leech-Pepin <jonathan.leechpepin@gmail.com>2014-11-21 08:08:33 -0500
committerJonathan Leech-Pepin <jonathan.leechpepin@gmail.com>2014-11-21 08:08:33 -0500
commit7fc59f07e565ee1e0696b8ca61b8faa6f480a768 (patch)
tree047d50c43ba2923cb69cf44617074a9246e499a1 /sx.el
parentbb4d8791f6cafeb0b87aa512aab2f0a97e8c0d3d (diff)
parent1dfd91e7373160854eeb85582598e6c8cc1b3561 (diff)
Merge branch 'master' into invalidate-cache
Conflicts: sx-cache.el - RESOLVED
Diffstat (limited to 'sx.el')
-rw-r--r--sx.el93
1 files changed, 74 insertions, 19 deletions
diff --git a/sx.el b/sx.el
index 64c555c..061c85d 100644
--- a/sx.el
+++ b/sx.el
@@ -1,8 +1,12 @@
-;;; sx.el --- core functions -*- lexical-binding: t; -*-
+;;; sx.el --- Core functions of the sx package. -*- lexical-binding: t; -*-
;; Copyright (C) 2014 Sean Allred
;; Author: Sean Allred <code@seanallred.com>
+;; URL: https://github.com/vermiculus/stack-mode/
+;; Version: 0.1
+;; Keywords: help, hypermedia, tools
+;; Package-Requires: ((emacs "24.1") (cl-lib "0.5") (json "1.3") (markdown-mode "2.0"))
;; 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
@@ -24,11 +28,41 @@
;;; Code:
+(defconst sx-version "0.1" "Version of the `sx' package.")
+
+
+;;; User commands
+(defun sx-version ()
+ "Print and return the version of the `sx' package."
+ (interactive)
+ (message "%s: %s" 'sx-version sx-version)
+ sx-version)
+
+;;;###autoload
+(defun sx-bug-report ()
+ "File a bug report about the `sx' package."
+ (interactive)
+ (browse-url "https://github.com/vermiculus/stack-mode/issues/new"))
+
;;; Utility Functions
+(defmacro sx-sorted-insert-skip-first (newelt list &optional predicate)
+ "Inserted NEWELT into LIST sorted by PREDICATE.
+This is designed for the (site id id ...) lists. So the first car
+is intentionally skipped."
+ `(let ((tail ,list)
+ (x ,newelt))
+ (while (and ;; We're not at the end.
+ (cdr-safe tail)
+ ;; We're not at the right place.
+ (,(or predicate #'<) x (cadr tail)))
+ (setq tail (cdr tail)))
+ (setcdr tail (cons x (cdr tail)))))
+
(defun sx-message (format-string &rest args)
- "Display a message"
+ "Display FORMAT-STRING as a message with ARGS.
+See `format'."
(message "[stack] %s" (apply #'format format-string args)))
(defun sx-message-help-echo ()
@@ -37,8 +71,11 @@
(when echo (message "%s" echo))))
(defun sx--thing-as-string (thing &optional sequence-sep)
- "Return a string representation of THING. If THING is already
-a string, just return it."
+ "Return a string representation of THING.
+If THING is already a string, just return it.
+
+Optional argument SEQUENCE-SEP is the separator applied between
+elements of a sequence."
(cond
((stringp thing) thing)
((symbolp thing) (symbol-name thing))
@@ -48,7 +85,24 @@ a string, just return it."
thing (if sequence-sep sequence-sep ";")))))
(defun sx--filter-data (data desired-tree)
- "Filters DATA and returns the DESIRED-TREE"
+ "Filter DATA and return the DESIRED-TREE.
+
+For example:
+
+ (sx--filter-data
+ '((prop1 . value1)
+ (prop2 . value2)
+ (prop3
+ (test1 . 1)
+ (test2 . 2))
+ (prop4 . t))
+ '(prop1 (prop3 test2)))
+
+would yield
+
+ ((prop1 . value1)
+ (prop3
+ (test2 . 2)))"
(if (vectorp data)
(apply #'vector
(mapcar (lambda (entry)
@@ -58,7 +112,7 @@ a string, just return it."
(delq
nil
(mapcar (lambda (cons-cell)
- ;; TODO the resolution of `f' is O(2n) in the worst
+ ;; @TODO the resolution of `f' is O(2n) in the worst
;; case. It may be faster to implement the same
;; functionality as a `while' loop to stop looking the
;; list once it has found a match. Do speed tests.
@@ -78,7 +132,7 @@ a string, just return it."
;;; Interpreting request data
(defun sx--deep-dot-search (data)
"Find symbols somewhere inside DATA which start with a `.'.
-Returns a list where each element is a cons cell. The car is the
+Returns a list where each element is a cons cell. The car is the
symbol, the cdr is the symbol without the `.'."
(cond
((symbolp data)
@@ -93,13 +147,13 @@ symbol, the cdr is the symbol without the `.'."
(remove nil (mapcar #'sx--deep-dot-search data))))))
(defmacro sx-assoc-let (alist &rest body)
- "Execute BODY while let-binding dotted symbols to their values in ALIST.
-Dotted symbol is any symbol starting with a `.'. Only those
+ "Use dotted symbols let-bound to their values in ALIST and execute BODY.
+Dotted symbol is any symbol starting with a `.'. Only those
present in BODY are letbound, which leads to optimal performance.
-For instance the following code
+For instance, the following code
- (stack-core-with-data alist
+ (sx-assoc-let alist
(list .title .body))
is equivalent to
@@ -116,19 +170,19 @@ is equivalent to
(defcustom sx-init-hook nil
"Hook run when stack-mode initializes.
-
-Run after `sx-init--internal-hook'.")
+Run after `sx-init--internal-hook'."
+ :group 'sx
+ :type 'hook)
(defvar sx-init--internal-hook nil
"Hook run when stack-mode initializes.
-
This is used internally to set initial values for variables such
as filters.")
-(defun sx--< (property x y &optional pred)
- "Non-nil if PROPERTY attribute of question X is less than that of Y.
-With optional argument predicate, use it instead of `<'."
- (funcall (or pred #'<)
+(defun sx--< (property x y &optional predicate)
+ "Non-nil if PROPERTY attribute of alist X is less than that of Y.
+With optional argument PREDICATE, use it instead of `<'."
+ (funcall (or predicate #'<)
(cdr (assoc property x))
(cdr (assoc property y))))
@@ -143,13 +197,14 @@ SETTER should be a function of two arguments. If SETTER is nil,
(,(or setter #'setq) ,variable ,value))))
nil)
-(defvar sx-initialized nil
+(defvar sx-initialized nil
"Nil if sx hasn't been initialized yet.
If it has, holds the time at which initialization happened.")
(defun sx-initialize (&optional force)
"Run initialization hooks if they haven't been run yet.
These are `sx-init--internal-hook' and `sx-init-hook'.
+
If FORCE is non-nil, run them even if they've already been run."
(when (or force (not sx-initialized))
(prog1