github actions #1
|
|
@ -14,7 +14,7 @@ jobs:
|
|||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
emacs_version: [25.1, 26.3]
|
||||
ruby-version: [2.6]
|
||||
ruby_version: [2.6]
|
||||
include:
|
||||
- emacs_version: 24.1
|
||||
lint_ignore: 1
|
||||
|
|
@ -26,13 +26,17 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: ${{ matrix.ruby_version }}
|
||||
|
||||
- uses: purcell/setup-emacs@master
|
||||
with:
|
||||
version: ${{ matrix.emacs_version }}
|
||||
|
||||
- uses: dickmao/setup-paths@master
|
||||
with:
|
||||
paths: local/bin:local/cask/bin:.rbenv/bin
|
||||
paths: local/bin:local/cask/bin
|
||||
|
||||
- uses: actions/cache@v1
|
||||
if: startsWith(runner.os, 'Linux')
|
||||
|
|
@ -46,13 +50,6 @@ jobs:
|
|||
path: ~/Library/Caches/rubocop_cache
|
||||
key: ${{ runner.os }}-rubocop
|
||||
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.rbenv
|
||||
key: ${{ runner.os }}-rbenv-${{ hashFiles('**/.ruby-version') }}
|
||||
restore-keys: |
|
||||
{{ runner.os }}-rbenv-
|
||||
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/local
|
||||
|
|
@ -68,24 +65,16 @@ jobs:
|
|||
path: ~/.cask
|
||||
key: cask-000
|
||||
|
||||
- name: macos-rbenv
|
||||
if: startsWith(runner.os, 'macOS')
|
||||
run: brew list rbenv &>/dev/null || HOMEBREW_NO_AUTO_UPDATE=1 brew install rbenv
|
||||
|
||||
- name: linux-rbenv
|
||||
if: startsWith(runner.os, 'Linux')
|
||||
uses: |
|
||||
masa-iwasaki/setup-rbenv@v1
|
||||
|
||||
- name: ruby
|
||||
run: |
|
||||
eval "eval $(rbenv init - --no-rehash)"
|
||||
rbenv install -s ${{ matrix.ruby-version }}
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: nndiscourse/vendor/bundle
|
||||
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gems-
|
||||
|
||||
- name: bundler
|
||||
run: |
|
||||
eval "eval $(rbenv init - --no-rehash)"
|
||||
gem install bundler
|
||||
gem install --user-install bundler
|
||||
|
||||
- name: apt-get
|
||||
if: startsWith(runner.os, 'Linux')
|
||||
|
|
@ -113,5 +102,4 @@ jobs:
|
|||
|
||||
- name: test
|
||||
run: |
|
||||
eval "eval $(rbenv init - --no-rehash)"
|
||||
make test
|
||||
|
|
|
|||
8
Makefile
8
Makefile
|
|
@ -3,7 +3,7 @@ export CASK := $(shell which cask)
|
|||
ifeq ($(CASK),)
|
||||
$(error Please install CASK at https://cask.readthedocs.io/en/latest/guide/installation.html)
|
||||
endif
|
||||
CASK_DIR := $(shell EMACS=$(EMACS) cask package-directory || exit 1)
|
||||
CASK_DIR := $(shell $(CASK) package-directory || exit 1)
|
||||
SRC = $(shell $(CASK) files)
|
||||
PKBUILD = 2.3
|
||||
VERSION = $(shell $(CASK) version)
|
||||
|
|
@ -17,6 +17,12 @@ ELCTESTS = $(TESTSSRC:.el=.elc)
|
|||
autoloads:
|
||||
$(EMACS) -Q --batch --eval "(package-initialize)" --eval "(package-generate-autoloads \"nndiscourse\" \".\")"
|
||||
|
||||
README.rst: README.in.rst nndiscourse.el
|
||||
grep ';;' nndiscourse.el \
|
||||
| awk '/;;;\s*Commentary/{within=1;next}/;;;\s*/{within=0}within' \
|
||||
| sed -e 's/^\s*;;*\s*//g' \
|
||||
| tools/readme-sed.sh "COMMENTARY" README.in.rst > README.rst
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(CASK) clean-elc
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
|build-status|
|
||||
|
||||
.. COMMENTARY (see Makefile)
|
||||
|
||||
.. |build-status|
|
||||
image:: https://github.com/dickmao/nndiscourse/workflows/CI/badge.svg
|
||||
:target: https://github.com/dickmao/nndiscourse/actions
|
||||
:alt: Build Status
|
||||
.. |melpa-dev|
|
||||
image:: http://melpa.milkbox.net/packages/nndiscourse-badge.svg
|
||||
:target: http://melpa.milkbox.net/#/nndiscourse
|
||||
:alt: MELPA development version
|
||||
|
||||
.. image:: screenshot.png
|
||||
.. |--| unicode:: U+2013 .. en dash
|
||||
.. |---| unicode:: U+2014 .. em dash, trimming surrounding whitespace
|
||||
:trim:
|
||||
|
||||
Install
|
||||
=======
|
||||
As described in `Getting started`_, ensure melpa's whereabouts in ``init.el`` or ``.emacs``::
|
||||
|
||||
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
|
||||
|
||||
Then
|
||||
|
||||
::
|
||||
|
||||
M-x package-refresh-contents RET
|
||||
M-x package-install RET nndiscourse RET
|
||||
|
||||
Alternatively, directly clone this repo and ``make install``.
|
||||
|
||||
Also see Troubleshooting_.
|
||||
|
||||
Usage
|
||||
=====
|
||||
In your ``.emacs`` or ``init.el``, use ONE of the following:
|
||||
|
||||
::
|
||||
|
||||
;; Applies to first-time Gnus users
|
||||
(custom-set-variables '(gnus-select-method (quote (nndiscourse ""))))
|
||||
|
||||
or, if you're an existing Gnus user,
|
||||
|
||||
::
|
||||
|
||||
;; Applies to existing Gnus users
|
||||
(add-to-list 'gnus-secondary-select-methods '(nndiscourse ""))
|
||||
|
||||
Then ``M-x gnus``.
|
||||
|
||||
Select a topic category via ``RET``. Rapidly catch yourself up via ``N`` and ``P``. Instantly catch-up with ``c``.
|
||||
|
||||
From the ``*Group*`` buffer, press ``g`` to refresh all categories. ``M-g`` on a particular category to refresh individually.
|
||||
|
||||
From the summary buffer, ``/o`` redisplays posts already read. ``x`` undisplays them.
|
||||
|
||||
Gnus beginners may find the interface bewildering. In particular, categories with no unread posts do not display. Use ``L`` to bring them out of hiding.
|
||||
|
||||
Troubleshooting
|
||||
===============
|
||||
Clone this repo. Then install Cask_. Then try ``make test-run-interactive``.
|
||||
|
||||
.. _Cask: https://cask.readthedocs.io/en/latest/guide/installation.html
|
||||
.. _Getting started: http://melpa.org/#/getting-started
|
||||
68
README.rst
68
README.rst
|
|
@ -1 +1,67 @@
|
|||
Read ``emacs-china.org`` in Gnus.
|
||||
|build-status|
|
||||
|
||||
A Gnus backend for Discourse.
|
||||
|
||||
.. |build-status|
|
||||
image:: https://github.com/dickmao/nndiscourse/workflows/CI/badge.svg
|
||||
:target: https://github.com/dickmao/nndiscourse/actions
|
||||
:alt: Build Status
|
||||
.. |melpa-dev|
|
||||
image:: http://melpa.milkbox.net/packages/nndiscourse-badge.svg
|
||||
:target: http://melpa.milkbox.net/#/nndiscourse
|
||||
:alt: MELPA development version
|
||||
|
||||
.. image:: screenshot.png
|
||||
.. |--| unicode:: U+2013 .. en dash
|
||||
.. |---| unicode:: U+2014 .. em dash, trimming surrounding whitespace
|
||||
:trim:
|
||||
|
||||
Install
|
||||
=======
|
||||
As described in `Getting started`_, ensure melpa's whereabouts in ``init.el`` or ``.emacs``::
|
||||
|
||||
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
|
||||
|
||||
Then
|
||||
|
||||
::
|
||||
|
||||
M-x package-refresh-contents RET
|
||||
M-x package-install RET nndiscourse RET
|
||||
|
||||
Alternatively, directly clone this repo and ``make install``.
|
||||
|
||||
Also see Troubleshooting_.
|
||||
|
||||
Usage
|
||||
=====
|
||||
In your ``.emacs`` or ``init.el``, use ONE of the following:
|
||||
|
||||
::
|
||||
|
||||
;; Applies to first-time Gnus users
|
||||
(custom-set-variables '(gnus-select-method (quote (nndiscourse ""))))
|
||||
|
||||
or, if you're an existing Gnus user,
|
||||
|
||||
::
|
||||
|
||||
;; Applies to existing Gnus users
|
||||
(add-to-list 'gnus-secondary-select-methods '(nndiscourse ""))
|
||||
|
||||
Then ``M-x gnus``.
|
||||
|
||||
Select a topic category via ``RET``. Rapidly catch yourself up via ``N`` and ``P``. Instantly catch-up with ``c``.
|
||||
|
||||
From the ``*Group*`` buffer, press ``g`` to refresh all categories. ``M-g`` on a particular category to refresh individually.
|
||||
|
||||
From the summary buffer, ``/o`` redisplays posts already read. ``x`` undisplays them.
|
||||
|
||||
Gnus beginners may find the interface bewildering. In particular, categories with no unread posts do not display. Use ``L`` to bring them out of hiding.
|
||||
|
||||
Troubleshooting
|
||||
===============
|
||||
Clone this repo. Then install Cask_. Then try ``make test-run-interactive``.
|
||||
|
||||
.. _Cask: https://cask.readthedocs.io/en/latest/guide/installation.html
|
||||
.. _Getting started: http://melpa.org/#/getting-started
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Scenario: install
|
|||
And I go to word "david"
|
||||
And I press "RET"
|
||||
And I switch to buffer "*Article nndiscourse+meta.discourse.org:bug*"
|
||||
Then I should see ":eyes:"
|
||||
Then I should see "Recent Changes"
|
||||
Then prospective unreads for "nndiscourse+meta.discourse.org:bug" is 1
|
||||
And I switch to buffer "*Summary nndiscourse+meta.discourse.org:bug*"
|
||||
And I press "q"
|
||||
|
|
|
|||
|
|
@ -262,6 +262,8 @@ Starting in emacs-src commit c1b63af, Gnus moved from obarrays to normal hashtab
|
|||
(make-mutex "nndiscourse--mutex-rpc-request"))
|
||||
"Only one jsonrpc output buffer, so avoid two requests using at the same time.")
|
||||
|
||||
(declare-function set-process-thread "process" t t) ;; emacs-25
|
||||
|
||||
(defun nndiscourse-rpc-request (server method &rest args)
|
||||
"Make jsonrpc call to SERVER invoking METHOD ARGS.
|
||||
|
||||
|
|
@ -277,7 +279,7 @@ reinstantiated with every call.
|
|||
|
||||
Return response of METHOD ARGS of type `json-object-type' or nil if failure."
|
||||
(when (and (nndiscourse-good-server server) (nndiscourse-server-opened server))
|
||||
(condition-case-unless-debug err
|
||||
(condition-case err
|
||||
(let* ((port (nndiscourse-proc-info-port
|
||||
(cdr (assoc server nndiscourse-processes))))
|
||||
(connection (json-rpc-connect nndiscourse-localhost port)))
|
||||
|
|
@ -400,6 +402,47 @@ I am counting on `gnus-check-server` in `gnus-read-active-file-1' in
|
|||
(unless original-global-rbenv-mode
|
||||
(global-rbenv-mode -1))))))
|
||||
|
||||
(defun nndiscourse-alist-get (key alist &optional default remove testfn)
|
||||
"Replicated library function for emacs-25.
|
||||
|
||||
Same argument meanings for KEY ALIST DEFAULT REMOVE and TESTFN."
|
||||
(ignore remove)
|
||||
(let ((x (if (not testfn)
|
||||
(assq key alist)
|
||||
(assoc key alist))))
|
||||
(if x (cdr x) default)))
|
||||
|
||||
(gv-define-expander nndiscourse-alist-get
|
||||
(lambda (do key alist &optional default remove testfn)
|
||||
(macroexp-let2 macroexp-copyable-p k key
|
||||
(gv-letplace (getter setter) alist
|
||||
(macroexp-let2 nil p `(if (and ,testfn (not (eq ,testfn 'eq)))
|
||||
(assoc ,k ,getter)
|
||||
(assq ,k ,getter))
|
||||
(funcall do (if (null default) `(cdr ,p)
|
||||
`(if ,p (cdr ,p) ,default))
|
||||
(lambda (v)
|
||||
(macroexp-let2 nil v v
|
||||
(let ((set-exp
|
||||
`(if ,p (setcdr ,p ,v)
|
||||
,(funcall setter
|
||||
`(cons (setq ,p (cons ,k ,v))
|
||||
,getter)))))
|
||||
`(progn
|
||||
,(cond
|
||||
((null remove) set-exp)
|
||||
((or (eql v default)
|
||||
(and (eq (car-safe v) 'quote)
|
||||
(eq (car-safe default) 'quote)
|
||||
(eql (cadr v) (cadr default))))
|
||||
`(if ,p ,(funcall setter `(delq ,p ,getter))))
|
||||
(t
|
||||
`(cond
|
||||
((not (eql ,default ,v)) ,set-exp)
|
||||
(,p ,(funcall setter
|
||||
`(delq ,p ,getter))))))
|
||||
,v))))))))))
|
||||
|
||||
(defun nndiscourse-register-process (port proc)
|
||||
"Register PORT and PROC with a server-name-qua-url.
|
||||
Return PROC if success, nil otherwise."
|
||||
|
|
@ -409,7 +452,8 @@ Return PROC if success, nil otherwise."
|
|||
(prog1 proc
|
||||
(gnus-message 5 "nndiscourse-register-process: registering %s"
|
||||
(process-name proc))
|
||||
(setf (alist-get (process-name proc) nndiscourse-processes nil nil #'equal)
|
||||
(setf (nndiscourse-alist-get (process-name proc) nndiscourse-processes
|
||||
nil nil #'equal)
|
||||
(make-nndiscourse-proc-info :port port :process proc)))
|
||||
(prog1 nil
|
||||
(gnus-message 3 "`nndiscourse-register-process': dead process %s"
|
||||
|
|
@ -418,12 +462,12 @@ Return PROC if success, nil otherwise."
|
|||
|
||||
(defun nndiscourse-deregister-process (server)
|
||||
"Disavow any knowledge of SERVER's process."
|
||||
(aif (alist-get server nndiscourse-processes nil nil #'equal)
|
||||
(aif (nndiscourse-alist-get server nndiscourse-processes nil nil #'equal)
|
||||
(let ((proc (nndiscourse-proc-info-process it)))
|
||||
(gnus-message 5 "`nndiscourse-deregister-process': deregistering %s %s pid=%s"
|
||||
server (process-name proc) (process-id proc))
|
||||
(delete-process proc)))
|
||||
(setf (alist-get server nndiscourse-processes nil nil #'equal) nil))
|
||||
(setf (nndiscourse-alist-get server nndiscourse-processes nil nil #'equal) nil))
|
||||
|
||||
(deffoo nndiscourse-close-server (&optional server _defs)
|
||||
"Patterning after nnimap.el."
|
||||
|
|
@ -531,7 +575,6 @@ Originally written by Paul Issartel."
|
|||
(nndiscourse--with-group server group
|
||||
(gnus-message 5 "nndiscourse-request-group-scan: scanning %s..." group)
|
||||
(nndiscourse-request-scan nil server)
|
||||
(gnus-activate-group gnus-newsgroup-name t nil (gnus-info-method info))
|
||||
(gnus-get-unread-articles-in-group
|
||||
(or info (gnus-get-info gnus-newsgroup-name))
|
||||
(gnus-active (gnus-info-group info)))
|
||||
|
|
@ -579,7 +622,8 @@ Originally written by Paul Issartel."
|
|||
(defun nndiscourse-get-categories (server)
|
||||
"Query SERVER /categories.json."
|
||||
(seq-filter (lambda (x) (eq json-false (plist-get x :read_restricted)))
|
||||
(funcall #'nndiscourse-rpc-request server "categories")))
|
||||
(let ((cats (funcall #'nndiscourse-rpc-request server "categories")))
|
||||
(if (seqp cats) cats nil))))
|
||||
|
||||
(cl-defun nndiscourse-get-topics (server slug &key (page 0))
|
||||
"Query SERVER /c/SLUG/l/latest.json, optionally for PAGE."
|
||||
|
|
@ -589,7 +633,9 @@ Originally written by Paul Issartel."
|
|||
|
||||
(cl-defun nndiscourse-get-posts (server &key (before 0))
|
||||
"Query SERVER /posts.json for posts before BEFORE."
|
||||
(plist-get (funcall #'nndiscourse-rpc-request server "posts" :before before) :latest_posts))
|
||||
(plist-get (let ((result (funcall #'nndiscourse-rpc-request server
|
||||
"posts" :before before)))
|
||||
(if (listp result) result nil)) :latest_posts))
|
||||
|
||||
(defun nndiscourse--number-to-header (server group topic-id post-number)
|
||||
"O(n) search for SERVER GROUP TOPIC-ID POST-NUMBER in headers."
|
||||
|
|
@ -603,16 +649,23 @@ Originally written by Paul Issartel."
|
|||
(= post-number* (plist-get plst :post_number))))))))
|
||||
(elt headers found)))
|
||||
|
||||
(defsubst nndiscourse-hash-count (table-or-obarray)
|
||||
"Return number items in TABLE-OR-OBARRAY."
|
||||
(let ((result 0))
|
||||
(nndiscourse--maphash (lambda (&rest _args) (cl-incf result)) table-or-obarray)
|
||||
result))
|
||||
|
||||
(defun nndiscourse--incoming (server)
|
||||
"Drink from the SERVER firehose."
|
||||
(interactive)
|
||||
(setq nndiscourse--debug-request-posts nil)
|
||||
(unless (nndiscourse--maphash #'cons nndiscourse--categories-hashtb)
|
||||
(when (zerop (nndiscourse-hash-count nndiscourse--categories-hashtb))
|
||||
(nndiscourse-request-list server))
|
||||
(cl-loop
|
||||
with new-posts
|
||||
for page-bottom = 1 then (plist-get (elt posts (1- (length posts))) :id)
|
||||
for posts = (nndiscourse-get-posts server :before (1- page-bottom))
|
||||
until (null posts)
|
||||
do (unless nndiscourse--last-id
|
||||
(setq nndiscourse--last-id
|
||||
(1- (plist-get (elt posts (1- (length posts))) :id))))
|
||||
|
|
@ -662,7 +715,7 @@ Originally written by Paul Issartel."
|
|||
(nconc (nndiscourse-get-headers server group) (list plst)))))
|
||||
(gnus-message
|
||||
5 (concat "nndiscourse--incoming: "
|
||||
(format "last-id: %d, " nndiscourse--last-id)
|
||||
(format "last-id: %s, " nndiscourse--last-id)
|
||||
(let ((result ""))
|
||||
(nndiscourse--maphash
|
||||
(lambda (key value)
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Install evm for Travis CI
|
||||
# or if already installed, then check for updates
|
||||
# Author: gonewest818 https://github.com/clojure-emacs/cider/pull/2139
|
||||
set -x
|
||||
|
||||
WORKDIR=${HOME}/local
|
||||
EVMDIR=$WORKDIR/evm
|
||||
|
||||
. tools/retry.sh
|
||||
|
||||
if [ -d $EVMDIR ]
|
||||
then
|
||||
cd $EVMDIR
|
||||
git pull origin master
|
||||
else
|
||||
git clone https://github.com/rejeep/evm.git $EVMDIR
|
||||
fi
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Create virtualenvs for python{2,3} for Travis CI on OSX
|
||||
|
||||
set -x
|
||||
|
||||
WORKDIR=${HOME}/local
|
||||
|
||||
. tools/retry.sh
|
||||
|
||||
if [ "x$TRAVIS_OS_NAME" = "xosx" ]; then
|
||||
brew list pyenv-virtualenv || HOMEBREW_NO_AUTO_UPDATE=1 brew install pyenv-virtualenv
|
||||
|
||||
case "${TOXENV}" in
|
||||
py27)
|
||||
pyenv install -s 2.7.13
|
||||
pyenv virtualenv -f 2.7.13 py27
|
||||
;;
|
||||
py35)
|
||||
pyenv install -s 3.5.2
|
||||
pyenv virtualenv -f 3.5.2 py35
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
Loading…
Reference in New Issue