Category Archives: geek

Extracting the xinput device number instead of hardcoding it

I’ve been using my wireless mouse more often these days. XWindows detected it fine and it works without a hitch, hooray! The downside is that as an additional input device, it threw my xinput device numbering off, so the script I was using to rotate the stylus input along with the screen on my tablet PC stopped working. Easy enough to fix by extracting the device number from the output of xinput using the cut command.

The relevant changes were:

xsetwacom set $(xinput | grep eraser | cut -c 55-56) rotate $direction
xsetwacom set $(xinput | grep touch | cut -c 55-56) rotate $direction
xsetwacom set $(xinput | grep stylus | cut -c 55-56) rotate $direction

My rotate-screen script on GitHub

Listing random npmjs.com packages updated today

I was looking for a way to randomly learn about packages hosted at npmjs.com so that I can come across libraries I might not have thought of searching for. The registry data is available at https://registry.npmjs.org/, and there’s a public CouchDB mirror at https://skimdb.npmjs.com/registry . Someday, when I know more about CouchDB, I might be able to query it and do other things.

In the meantime, this Github issue pointed me to a view of all packages modified today, which is a good-enough proxy for what I’m interested in.

Here’s an AngularJS app that displays the list and highlights a random item.

Screenshot_2016-02-20_21-09-21

<html ng-app="myApp">
  <head>
    <script type="text/javascript"
      src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
    <script>
     // https://registry.npmjs.org/-/all/static/today.json
     // from https://github.com/npm/npm-registry-couchapp/issues/242
     var app = angular.module('myApp', []);
     app.controller('npmTodayCtrl', function($scope, $http) {
       $scope.randomize = function() {
         $scope.random = $scope.packages[Math.floor(Math.random() * $scope.packages.length)];
       }
       $http.get('https://registry.npmjs.org/-/all/static/today.json').then(function(info) {
         $scope.packages = info.data;
         $scope.randomize();
       });
     });
    </script>
  </head>
  <body ng-controller="npmTodayCtrl">
    <div><a href="" ng-click="randomize()">Random highlight:</a></div>
    <div ng-if="random" style="margin-top: 1em; font-size: x-large">
      <strong><a ng-href="https://npmjs.com/package/{{random.name}}">{{random.name}}</a></strong>
      {{random.description}}
    </div>
    <hr>
    <table>
      <tr ng-repeat="package in packages">
        <td><a ng-href="https://npmjs.com/package/{{package.name}}">{{package.name}}</a></td>
        <td>{{package.description}}</td>
      </tr>
    </table>
  </body>
</html>

Building a today-I-learned habit, and displaying the documentation for random Emacs commands

I’d like to build a habit of regularly learning one small thing each day in one of three domains: tech, life, and learning. My measurable output would probably be in the form of index cards, tweets, blog posts, and notes (in org-capture, Dropbox, or Evernote). I can get input from various sources like blog posts, videos, books, webpages, and so on.

2016-02-19a Preparing for a today-I-learned habit -- index card #til #learning

2016-02-19a Preparing for a today-I-learned habit — index card #til #learning

A little bit of randomness might be useful for learning more about Emacs. Emacswiki has a random page function, but the chunks are often a little large or irrelevant. On the other hand, displaying a random command from the packages that I already have loaded into my Emacs – that might be a good way to discover interesting things.

I started by looking at apropos-command, which led me to apropos-internal, which is a C function that referred to obarray. Using obarray by itself didn’t work (suspiciously few elements, so I often ended up looking at emms-related functions). I eventually found mapatoms, which seems to do a better job at listing an appreciable number of interactive functions. I filtered the list to include only documented functions that had not been marked as obsolete: 8,415 in my current Emacs, which should be plenty to go through. =)

(defun my/describe-random-interactive-function ()
  (interactive)
  "Show the documentation for a random interactive function.
Consider only documented, non-obsolete functions."
  (let (result)
    (mapatoms
     (lambda (s)
       (when (and (commandp s) 
                  (documentation s t)
                  (null (get s 'byte-obsolete-info)))
         (setq result (cons s result)))))
    (describe-function (elt result (random (length result))))))

I’ve added this to a key-chord + hydra keymap as a repeatable function, so I can type hh to start my Hydra and then type r as many times as I want in order to show the documentation for a random interactive function. If you’re curious about that, you can see the key-chord section of my config.

Anyway, today I learned more about obarray and mapatoms – they’re not interactive functions, but they were handy for building this little bit of code. We’ll see how it goes! =)

2016-02-15 Emacs News

Links from reddit.com/r/emacs, /r/orgmode, Hacker News, planet.emacsen.org, Youtube, EmacsWiki:RecentChanges, the Emacs commit log, the changes to the Emacs NEWS file, and emacs-devel.

Past Emacs News round-ups

2016-02-08 Emacs News

Links from reddit.com/r/emacs, /r/orgmode, Hacker News, planet.emacsen.org, Youtube, EmacsWiki:RecentChanges, the Emacs commit log, the changes to the Emacs NEWS file, and emacs-devel.

Past Emacs News round-ups

Publishing Emacs News as plain text, HTML, and attached Org file

Update 2016-02-05: Since @ThierryStoehr linked to this post about Emacs News-related code, I figured I’d add a link to the other support functions I’ve been using to help me with Emacs News summarization. There’s also this bit:

(let ((date (org-read-date nil nil "-mon")))
    (concat
     (my/org-list-from-rss "http://planet.emacsen.org/atom.xml" date) "\n"
     (shell-command-to-string (concat "~/bin/list-reddit-links.coffee emacs " date)) "\n"
     (shell-command-to-string (concat "~/bin/list-reddit-links.coffee org-mode " date)) "\n"
     "- New packages:\n"
     (my/list-new-packages) 
     "\n"))

Handy little things!

——

I’ve been publishing these weekly summaries of Emacs-related links on my blog and to the emacs-tangents mailing list / newsgroup. I started by posting plain text from Org Mode’s ASCII export, and people asked for Org Mode and HTML formats. So here’s some code that prepares things for pasting into a Gnus message buffer.

It turns out that order matters for multipart/alternative – start with plain text, then include richer alternatives. First time around, I put the HTML version first, so people didn’t end up seeing it. Anyway, here’s something that shows up properly now: text/plain, then text/html, with text/x-org attached. The heavy lifting is done with org-export-string-as, which exports into different formats.

  (defun my/share-emacs-news ()
    "Prepare current subtree for yanking into post."
    (interactive)
    ;; Draft Gnus article
    (save-restriction
      (org-narrow-to-subtree)
      (let ((org-export-html-preamble nil)
            (org-html-toplevel-hlevel 3)
            output)
        (setq output
              (apply
               'format
               "<#multipart type=alternative>
<#part type=\"text/plain\" disposition=inline>
%s
<#/part>
<#part type=\"text/html\" disposition=inline>
%s
<#/part>
<#/multipart>
<#part type=\"text/x-org\" disposition=attachment name=\"emacs-news.org\">
%s
<#/part>
"
               (mapcar
                (lambda (format)
                  (org-export-string-as (buffer-substring (point-min) (point-max)) format t))
                '(ascii html org))))
        (kill-new output))))

Howard Abrams showed me something like this in June 2015’s Emacs Hangout (~1:18:26) using org-mime-org-buffer-htmlize, which probably does the job in a much cooler way. =) I thought he had a blog post about it, but I can’t seem to find it. Anyway, there’s my little hack above!