WEBVTT
00:00:00.799 --> 00:00:05.520
Hello, everyone, and welcome to this
short lightning talk:
00:00:05.520 --> 00:00:09.519
"Traverse Complex JSON Structures with
Live Feedback."
00:00:09.519 --> 00:00:18.000
This is a pre-recorded talk and part of
the EmacsConf 2020 schedule.
00:00:18.000 --> 00:00:19.439
This is what we're going to do.
00:00:19.439 --> 00:00:22.320
I'll make a quick introduction to the
topic at hand.
00:00:22.320 --> 00:00:24.400
I'll give you a demonstration of some
tools,
00:00:24.400 --> 00:00:29.199
and then we'll leave you
with the links to said tools.
00:00:29.199 --> 00:00:31.679
Before that, just a little bit about me.
00:00:31.679 --> 00:00:40.399
I am the CEO and co-founder of a company
based in the Swiss mountains called 200ok.ch.
00:00:40.399 --> 00:00:44.879
We are a product incubator and
service consultancy,
00:00:44.879 --> 00:00:50.000
but we like to spend most or at least as
much time as we can
00:00:50.000 --> 00:00:52.719
building free software.
00:00:52.719 --> 00:00:56.879
I'm also an ordained Zen monk and abbot
of the Lambda Zen temple.
00:00:56.879 --> 00:01:04.159
You can reach me anytime on questions
regarding Emacs, for example,
00:01:04.159 --> 00:01:07.200
at alain@200ok.ch.
00:01:07.200 --> 00:01:09.439
But back to the topic at hand.
00:01:09.439 --> 00:01:11.760
The proposition is as following:
00:01:11.760 --> 00:01:14.000
most work on the computer is based on
either
00:01:14.000 --> 00:01:16.479
text processing or text consumption.
00:01:16.479 --> 00:01:22.799
And very often, the text which you need
to process is in a structured format,
00:01:22.799 --> 00:01:24.560
for example, in JSON.
00:01:24.560 --> 00:01:28.560
That might even be if your job is not
programming per se.
00:01:28.560 --> 00:01:33.119
Reading through such a bigger chunk of
JSON can be non-trivial, however,
00:01:33.119 --> 00:01:36.479
while just reading and understanding it
00:01:36.479 --> 00:01:40.320
will be essential to getting your job
done.
00:01:40.320 --> 00:01:44.479
So let's quickly check out an example
JSON file.
00:01:44.479 --> 00:01:47.200
This is from the Github API,
00:01:47.200 --> 00:01:52.079
which is a request--sorry, the
response to a request
00:01:52.079 --> 00:01:54.640
for a specific issue on the github API.
00:01:54.640 --> 00:01:58.799
So let's quickly check that one out.
00:01:58.799 --> 00:02:01.920
Okay. So here it is open, and we can
already see
00:02:01.920 --> 00:02:05.439
that there is lots of stuff
going on here.
00:02:05.439 --> 00:02:07.360
It's 200 lines.
00:02:07.360 --> 00:02:09.200
It's not going to be very easy
00:02:09.200 --> 00:02:11.840
just to find out what are the top level
things in here,
00:02:11.840 --> 00:02:13.360
what are the top level attributes.
00:02:13.360 --> 00:02:17.840
Of course I can do this, and maybe do it
by hand, but that doesn't scale.
00:02:17.840 --> 00:02:21.599
I can use cool Emacs facilities like the
hideshow-mode
00:02:21.599 --> 00:02:24.720
and try to fold all the things that are
top level,
00:02:24.720 --> 00:02:27.200
but that also doesn't really scale.
00:02:27.200 --> 00:02:29.360
There must be a better way.
00:02:29.360 --> 00:02:32.000
Of course there is. There is prior art.
00:02:32.000 --> 00:02:34.080
There is a tool called jq.
00:02:34.080 --> 00:02:37.760
I'm going to quote the USP (unique selling proposition) from their website:
00:02:37.760 --> 00:02:42.000
jq is like sed for JSON data.
00:02:42.000 --> 00:02:46.319
you can use it to slice and filter and
map and transform structured data
00:02:46.319 --> 00:02:47.840
with the same ease that
00:02:47.840 --> 00:02:54.000
sed, awk, grep, and friends let you
play with text.
00:02:54.000 --> 00:02:56.879
Let me give you a quick demonstration of
it.
00:02:56.879 --> 00:02:59.040
By the way, it's written in portable C.
00:02:59.040 --> 00:03:03.519
It has zero runtime dependency, so it's
very easy to get started with it
00:03:03.519 --> 00:03:09.840
and use it on pretty much any UNIX-based
computer.
00:03:09.840 --> 00:03:14.000
Sorry, no, Linux-based computer,
apologies.
00:03:14.000 --> 00:03:18.720
Okay, so let's explore a
JSON file with it.
00:03:18.720 --> 00:03:20.000
It's a command line tool,
00:03:20.000 --> 00:03:24.000
and it has a very simple command
line syntax.
00:03:24.000 --> 00:03:29.840
So you call the binary and then you give
it a query and a file,
00:03:29.840 --> 00:03:32.560
and then it will return its answer.
00:03:32.560 --> 00:03:35.440
So, for example, if I want the top
level keys,
00:03:35.440 --> 00:03:38.000
I will just say jq keys the file
00:03:38.000 --> 00:03:39.840
and it will return the keys.
00:03:39.840 --> 00:03:44.400
Simple as that. So let's check this out
in a real shell.
00:03:44.400 --> 00:03:46.879
Here I am in eshell.
00:03:46.879 --> 00:03:51.440
Let's run jq keys on the Github issue comment.
00:03:51.440 --> 00:03:58.799
We can see that we have actually
received a list back here
00:03:58.799 --> 00:04:00.319
with the top-level things.
00:04:00.319 --> 00:04:02.879
So this issue... It looks very interesting.
00:04:02.879 --> 00:04:07.360
Let's ask it to give me more information on this issue.
00:04:07.360 --> 00:04:11.360
Then it's hairy again. That's a lot of stuff.
00:04:11.360 --> 00:04:14.560
I mean, lucky for us, we are in Emacs here,
00:04:14.560 --> 00:04:16.720
so we can use nice shortcuts.
00:04:16.720 --> 00:04:22.000
We can copy this. We can go in here, just select that,
00:04:22.000 --> 00:04:24.160
get that out or something like this.
00:04:24.160 --> 00:04:32.320
But still, this is not really the best way to do that, right?
00:04:32.320 --> 00:04:34.080
it gets kind of tedious.
00:04:34.080 --> 00:04:37.680
At this point the output can be humongous.
00:04:37.680 --> 00:04:41.919
The shell is not really the best place to read through such big output.
00:04:41.919 --> 00:04:45.759
I mean, eshell is probably one of the better shells for this,
00:04:45.759 --> 00:04:47.919
because it's just a regular Emacs buffer,
00:04:47.919 --> 00:04:50.720
but still, it's not really the best tool.
00:04:50.720 --> 00:04:53.680
I need to repeat the command all the time
00:04:53.680 --> 00:04:56.000
until I finally build the right query.
00:04:56.000 --> 00:04:59.840
And all the time, I lose my focus,
00:04:59.840 --> 00:05:02.800
I lose what I'm currently looking at.
00:05:02.800 --> 00:05:05.520
I'm seeing the new result.
00:05:05.520 --> 00:05:08.160
It would be so much nicer to have live feedback.
00:05:08.160 --> 00:05:10.720
When working with Emacs, we're quite used to that.
00:05:10.720 --> 00:05:12.320
So there should be an option.
00:05:12.320 --> 00:05:15.120
And of course there is. It's Emacs, right,
00:05:15.120 --> 00:05:17.759
so you can do anything.
00:05:17.759 --> 00:05:22.960
There is various good tools for completion in Emacs.
00:05:22.960 --> 00:05:26.000
I used ivy for this.
00:05:26.000 --> 00:05:29.039
I'm going to quote the USP for ivy.
00:05:29.039 --> 00:05:32.639
ivy is a generic completion mechanism for Emacs.
00:05:32.639 --> 00:05:37.919
While it operates similarly to other completion schemes such as icomplete mode,
00:05:37.919 --> 00:05:42.160
ivy aims to be more efficient, smaller, simpler, and smoother to use,
00:05:42.160 --> 00:05:45.199
yet highly customizable.
00:05:45.199 --> 00:05:46.479
And that's true.
00:05:46.479 --> 00:05:49.440
One of the cool things of ivy
00:05:49.440 --> 00:05:54.320
compared to other completion mechanisms in Emacs
00:05:54.320 --> 00:05:59.120
is that it can be used on dynamic data.
00:05:59.120 --> 00:06:02.400
So usually completion works on a static input.
00:06:02.400 --> 00:06:05.360
For example, you're in a buffer, a text buffer,
00:06:05.360 --> 00:06:09.600
and you use isearch maybe with ido-mode,
00:06:09.600 --> 00:06:13.360
and you find your results. That's all nice.
00:06:13.360 --> 00:06:19.600
However, if I want to search on dynamic data,
00:06:19.600 --> 00:06:20.720
that doesn't work.
00:06:20.720 --> 00:06:24.880
So whenever I type in my query for jq,
00:06:24.880 --> 00:06:28.000
I actually need to call the jq binary,
00:06:28.000 --> 00:06:30.720
and it will give a different result set back.
00:06:30.720 --> 00:06:36.160
So it's a really dynamic mechanism that we need here.
00:06:36.160 --> 00:06:38.240
It's much more like a search engine.
00:06:38.240 --> 00:06:41.440
ivy luckily has something built in,
00:06:41.440 --> 00:06:43.520
and it's called counsel.
00:06:43.520 --> 00:06:47.360
So I used counsel and jq and combined them,
00:06:47.360 --> 00:06:49.199
and built a new package
00:06:49.199 --> 00:06:52.960
with which we can use Emacs and jq
00:06:52.960 --> 00:06:56.000
to have live feedback.
00:06:56.000 --> 00:06:57.759
It's very easy to use.
00:06:57.759 --> 00:06:59.840
So you just call counsel-jq
00:06:59.840 --> 00:07:02.160
on a buffer containing JSON.
00:07:02.160 --> 00:07:04.319
For example, the one we have here.
00:07:04.319 --> 00:07:06.800
Let's call counsel-jq on it,
00:07:06.800 --> 00:07:10.080
and we already get a default query,
00:07:10.080 --> 00:07:14.639
the dot query, which just gives us the same file.
00:07:14.639 --> 00:07:16.240
But now we can change it.
00:07:16.240 --> 00:07:18.639
For example, find all the keys in here.
00:07:18.639 --> 00:07:20.319
And then we see I had this issue.
00:07:20.319 --> 00:07:22.800
This was the one that we were interested in.
00:07:22.800 --> 00:07:25.599
So let's find more information on the issue.
00:07:25.599 --> 00:07:28.720
What keys does it have actually have?
00:07:28.720 --> 00:07:31.680
It has assignees. That interests me.
00:07:31.680 --> 00:07:34.800
So let's check out the assignees in here.
00:07:34.800 --> 00:07:39.759
There's two of them, but I'm only interested in the first one.
00:07:39.759 --> 00:07:43.599
I'm making stuff up as I go here, of course.
00:07:43.599 --> 00:07:47.039
Whenever I hit enter, I get a new buffer
00:07:47.039 --> 00:07:52.639
which just shows me this particular result
00:07:52.639 --> 00:07:55.599
for the particular query that I entered.
00:07:55.599 --> 00:07:57.680
So let me do that again.
00:07:57.680 --> 00:08:04.000
We are in here. We are looking at a JSON file.
00:08:04.000 --> 00:08:05.840
This can be very, very big.
00:08:05.840 --> 00:08:07.280
Doesn't also need to be a file.
00:08:07.280 --> 00:08:09.520
Just needs to be a buffer.
00:08:09.520 --> 00:08:11.360
You call counsel-jq on it,
00:08:11.360 --> 00:08:14.319
and you can do any kind of query on it.
00:08:14.319 --> 00:08:18.080
For example, let's see if there is a URL here.
00:08:18.080 --> 00:08:19.440
Yes, there's a URL.
00:08:19.440 --> 00:08:22.827
Let's see if there's a repository here.
00:08:22.827 --> 00:08:24.639
Repository. No, there isn't.
00:08:24.639 --> 00:08:33.440
What was it called? Issue. Keys. Repository URL, it was called.
00:08:33.440 --> 00:08:38.240
So let's see issue repository URL,
00:08:38.240 --> 00:08:39.519
and then we see.
00:08:39.519 --> 00:08:44.800
So apparently this issue comment is for a repository called organice.
00:08:44.800 --> 00:08:47.839
I wonder what that might be.
00:08:47.839 --> 00:08:52.640
Okay. So that was a very short introduction to counsel-jq.
00:08:52.640 --> 00:08:54.240
You can see the timer here.
00:08:54.240 --> 00:08:57.440
I only have one minute left to go, so I'm going to leave
00:08:57.440 --> 00:09:02.880
with a very, very short introduction to the counsel-jq code.
00:09:02.880 --> 00:09:06.000
It's not even 60 lines of elisp,
00:09:06.000 --> 00:09:09.600
so building something like this is very, very easy.
00:09:09.600 --> 00:09:14.560
I would encourage you to go and read through the code in your own time,
00:09:14.560 --> 00:09:17.519
if you're interested in building something like this.
00:09:17.519 --> 00:09:22.720
If you're interested in just using jq or you're done,
00:09:22.720 --> 00:09:24.320
these are the links to all the tools.
00:09:24.320 --> 00:09:28.240
counsel-jq, of course, is readily available on MELPA.
00:09:28.240 --> 00:09:32.959
Also developed under the AGPL license on Github.
00:09:32.959 --> 00:09:36.080
And this organice thing, by the way, it's
00:09:36.080 --> 00:09:38.560
Org Mode for mobile and desktop browsers.
00:09:38.560 --> 00:09:43.120
Also a great free software tool maybe that interests you.
00:09:43.120 --> 00:09:46.240
Thank you for listening. Have a great time.
00:09:46.240 --> 00:09:49.360
10 seconds left. I am going to stop this now.
00:09:49.360 --> 00:09:53.920
Enjoy EmacsConf. Have a great day.