From f6699988fd521703c1d44489e3d89c6f71d418df Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Tue, 11 Nov 2014 12:12:30 -0500 Subject: Move question sorting function to sx.el It is not specific to questions -- it is generally applicable to any alist. --- sx.el | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sx.el') diff --git a/sx.el b/sx.el index 6165714..0a1b046 100644 --- a/sx.el +++ b/sx.el @@ -160,6 +160,13 @@ Run after `sx-init--internal-hook'.") 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 #'<) + (cdr (assoc property x)) + (cdr (assoc property y)))) + (defmacro sx-init-variable (variable value &optional setter) "Set VARIABLE to VALUE using SETTER. SETTER should be a function of two arguments. If SETTER is nil, -- cgit v1.2.3 From 7d7c996aa723a9c99d8ceeecc7891a7049e69c98 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Fri, 14 Nov 2014 23:58:05 +0000 Subject: Quick-fix assoc-let --- sx.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sx.el') diff --git a/sx.el b/sx.el index 7ed56d3..796a5d6 100644 --- a/sx.el +++ b/sx.el @@ -106,7 +106,7 @@ is equivalent to (debug t)) (let ((symbol-alist (sx--deep-dot-search body))) `(let ,(mapcar (lambda (x) `(,(car x) (cdr (assoc ',(cdr x) ,alist)))) - symbol-alist) + (delete-dups symbol-alist)) ,@body))) (defcustom sx-init-hook nil -- cgit v1.2.3 From 3565241b2afcf81741c631bfba45304815ce847f Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 15 Nov 2014 00:18:35 +0000 Subject: Several navigation improvements. --- sx-question-mode.el | 76 +++++++++++++++++++++++++++++++---------------------- sx.el | 5 ++++ 2 files changed, 49 insertions(+), 32 deletions(-) (limited to 'sx.el') diff --git a/sx-question-mode.el b/sx-question-mode.el index 4942889..d08fc0d 100644 --- a/sx-question-mode.el +++ b/sx-question-mode.el @@ -159,7 +159,7 @@ editor's name." :group 'sx-question-mode) (defcustom sx-question-mode-separator - (concat "\n" (make-string 80 ?_) "\n") + (concat (make-string 80 ?_) "\n") "Separator used between header and body." :type 'string :group 'sx-question-mode) @@ -203,22 +203,33 @@ QUESTION must be a data structure returned by `json-read'." (with-selected-window sx-question-mode--window (sx-question-mode-next-section))) +(defvar sx-question-mode--section-help-echo + (format + (propertize "%s to hide/display content" 'face 'minibuffer-prompt) + (propertize "RET" 'face 'font-lock-function-name-face)) + "") + +(defvar sx-question-mode--title-properties + '(face sx-question-mode-title + action sx-question-mode-hide-show-section + help-echo sx-question-mode--section-help-echo) + "") + (defun sx-question-mode--print-section (data) "Print a section corresponding to DATA. DATA can represent a question or an answer." (sx-assoc-let data (insert sx-question-mode-header-title - (if .title - ;; Questions have title - (propertize - .title - 'face 'sx-question-mode-title - 'sx-question-mode--section 1) - ;; Answers don't - (propertize - sx-question-mode-answer-title - 'face 'sx-question-mode-title - 'sx-question-mode--section 2))) + (apply + #'propertize + ;; Questions have title + (or .title + ;; Answers don't + sx-question-mode-answer-title) + ;; Section level + 'sx-question-mode--section (if .title 1 2) + ;; face, action and help-echo + sx-question-mode--title-properties)) ;; Sections can be hidden with overlays (sx-question-mode--wrap-in-overlay '(sx-question-mode--section-content t) @@ -243,8 +254,10 @@ DATA can represent a question or an answer." (mapconcat #'sx-question--tag-format .tags " ") 'sx-question-mode-tags)) ;; Body - (insert (propertize sx-question-mode-separator - 'face 'sx-question-mode-header)) + (insert "\n" + (propertize sx-question-mode-separator + 'face 'sx-question-mode-header + 'sx-question-mode--section 4)) (sx-question-mode--wrap-in-overlay '(face sx-question-mode-content-face) (insert "\n" @@ -254,12 +267,12 @@ DATA can represent a question or an answer." 'face 'sx-question-mode-header)))) ;; Comments (when .comments - (insert - "\n" - (propertize - sx-question-mode-comments-title - 'face 'sx-question-mode-title-comments - 'sx-question-mode--section 3)) + (insert "\n" + (apply #'propertize + sx-question-mode-comments-title + 'face 'sx-question-mode-title-comments + 'sx-question-mode--section 3 + sx-question-mode--title-properties)) (sx-question-mode--wrap-in-overlay '(sx-question-mode--section-content t) (insert "\n") @@ -381,7 +394,7 @@ URL is used as 'help-echo and 'url properties." (propertize text ;; Mouse-over - 'help-echo (format + 'help-echo (format (propertize "URL: %s, %s to visit" 'face 'minibuffer-prompt) (propertize url 'face 'default) (propertize "RET" 'face 'font-lock-function-name-face)) @@ -391,9 +404,7 @@ URL is used as 'help-echo and 'url properties." 'face 'link 'mouse-face 'highlight ;; What RET calls - 'action #'sx-question-mode-follow-link - ;; This is for `sx-question-mode--goto-propety-change'. - 'sx-question-mode--action #'sx-question-mode-follow-link)) + 'action #'sx-question-mode-follow-link)) (defun sx-question-mode-follow-link (&optional pos) "Follow link at POS or point" @@ -442,18 +453,21 @@ If nil, no recentering is performed." "Move down to next section (question or answer) of this buffer. Prefix argument N moves N sections down or up." (interactive "p") - (unless n (setq n 1)) + (or n (setq n 1)) (dotimes (_ (abs n)) ;; This will either move us to the next section, or move out of ;; the current one. - (unless (sx-question-mode--goto-propety-change 'section n) + (unless (sx-question-mode--goto-propety-change + 'sx-question-mode--section n) ;; If all we did was move out the current one, then move again ;; and we're guaranteed to reach the next section. - (sx-question-mode--goto-propety-change 'section n))) + (sx-question-mode--goto-propety-change + 'sx-question-mode--section n))) (when sx-question-mode-recenter-line (let ((ov (car-safe (sx-question-mode--section-overlays-at (line-end-position))))) (when (and (overlayp ov) (> (overlay-end ov) (window-end))) - (recenter sx-question-mode-recenter-line))))) + (recenter sx-question-mode-recenter-line)))) + (sx-message-help-echo)) (defun sx-question-mode-previous-section (&optional n) "Move down to previous section (question or answer) of this buffer. @@ -470,8 +484,7 @@ With prefix argument N, move N times." (dotimes (_ (abs n)) (unless (sx-question-mode--goto-propety-change 'action n) (sx-question-mode--goto-propety-change 'action n))) - (let ((echo (get-text-property (point) 'help-echo))) - (when echo (message "%s" echo)))) + (sx-message-help-echo)) (defun sx-question-mode-previous-button (&optional n) "Move to previous interactible object in this buffer. @@ -484,8 +497,7 @@ With prefix argument N, move N times." "Move forward until the value of text-property `sx-question-mode--PROP' changes. Return the new value of PROP at point. If DIRECTION is negative, move backwards instead." - (let ((prop (intern (format "sx-question-mode--%s" prop))) - (func (if (and (numberp direction) + (let ((func (if (and (numberp direction) (< direction 0)) #'previous-single-property-change #'next-single-property-change)) diff --git a/sx.el b/sx.el index 7ed56d3..058230c 100644 --- a/sx.el +++ b/sx.el @@ -31,6 +31,11 @@ "Display a message" (message "[stack] %s" (apply #'format format-string args))) +(defun sx-message-help-echo () + "If there's a 'help-echo property under point, message it." + (let ((echo (get-text-property (point) 'help-echo))) + (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." -- cgit v1.2.3 From 829821cc988be06c1f8a0699d11fecb7a6db972a Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sun, 16 Nov 2014 10:45:21 +0000 Subject: Implement sx-initialize --- sx.el | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'sx.el') diff --git a/sx.el b/sx.el index 53aae84..64c555c 100644 --- a/sx.el +++ b/sx.el @@ -143,10 +143,19 @@ SETTER should be a function of two arguments. If SETTER is nil, (,(or setter #'setq) ,variable ,value)))) nil) -(defun stack-initialize () - (run-hooks - 'sx-init--internal-hook - 'sx-init-hook)) +(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 + (run-hooks 'sx-init--internal-hook + 'sx-init-hook) + (setq sx-initialized (current-time))))) (provide 'sx) ;;; sx.el ends here -- cgit v1.2.3