WEBVTT captioned by sachac, checked by sachac

NOTE Introduction

00:00.000 --> 00:00:04.897
Hi, I'm Jeff Trull, and today I'm going to talk to you

00:00:04.898 --> 00:00:08.460
about improving C++ compiler diagnostics

00:08.460 --> 00:13.600
using overlays and other features from Emacs.

00:13.600 --> 00:15.840
First an overview of my talk.

00:15.840 --> 00:00:17.656
I'm going to cover what overlays are

00:00:17.657 --> 00:00:19.325
and how you can use them in code,

00:00:19.326 --> 00:00:21.478
then I'm going to talk about C++

00:00:21.479 --> 00:00:24.480
and why its compiler errors can be so onerous.

00:24.480 --> 00:00:26.750
Finally, we'll take that information

00:00:26.751 --> 00:00:28.447
and build a new minor mode

00:00:28.448 --> 00:00:33.560
using overlays and other Emacs features.

NOTE Overlays and what they can do

00:33.560 --> 00:35.520
First of all, overlays.

00:35.520 --> 00:36.680
What are they?

00:36.680 --> 00:00:39.124
They are objects consisting of a buffer range

00:00:39.125 --> 00:00:40.400
and a set of properties.

00:40.400 --> 00:43.120
That means that they cover a region in a buffer.

00:43.120 --> 00:00:45.533
The properties can be a certain set

00:00:45.534 --> 00:00:47.344
of special property names,

00:00:47.345 --> 00:00:50.288
in which case they can be used to cause

00:00:50.289 --> 00:00:52.569
special effects in the buffer,

00:00:52.570 --> 00:00:55.660
but they never change the underlying text.

00:55.660 --> 00:59.900
You can use them for things like hiding things.

00:59.900 --> 00:01:02.886
So, for example, overlays are working right now

00:01:02.887 --> 00:01:04.660
in this window. `org-present`,

00:01:04.661 --> 00:01:07.595
the technology I'm using for this presentation,

00:01:07.596 --> 00:01:10.031
is hiding the asterisk before every headline,

00:01:10.032 --> 00:01:12.520
as well as the things called emphasis markers;

00:01:12.521 --> 00:01:16.269
that is, those things that make things look

00:01:16.270 --> 00:01:20.700
monospaced for verbatim, or italic, or bold.

01:20.700 --> 00:01:24.421
The special characters we use to mark off those sections

00:01:24.422 --> 00:01:28.940
are also hidden by `org-present` using overlays.

01:28.940 --> 00:01:30.601
But those things are still in the buffer

00:01:30.602 --> 00:01:31.980
and they're still visible to code.

01:31.980 --> 00:01:34.921
So if I run this little snippet of code down here,

00:01:34.922 --> 00:01:37.403
it's going to go up to the headline "Overlays

00:01:37.404 --> 00:01:40.051
and what they can do," and it's going to tell us

00:01:40.052 --> 00:01:41.540
what's there in the buffer.

01:41.540 --> 01:45.100
Let's go down and run this.

01:45.100 --> 00:01:48.957
So according to this code, the contents of the buffer

00:01:48.958 --> 00:01:51.990
to the left of the headline is a star in a space,

00:01:51.991 --> 00:01:55.204
which means that even though we can't see that star,

00:01:55.205 --> 00:01:58.220
it's still there, because it's hidden by an overlay.

01:58.220 --> 02:02.500
And that's kind of the essence of what overlays are.

NOTE Simple overlay example - creating an overlay

02:02.500 --> 02:04.780
Let's do a simple overlay example.

02:04.780 --> 00:02:06.719
We have some text on the right here,

00:02:06.720 --> 00:02:09.340
which is a famous poem by William Carlos Williams,

02:09.340 --> 02:12.180
which has been the subject of many memes.

02:12.180 --> 02:17.860
Let's create an overlay that covers it.

02:17.860 --> 02:20.700
I'll go down here and use this snippet of code here.

02:20.700 --> 00:02:25.918
We'll go up to the top, and we'll mark everything

00:02:25.919 --> 00:02:29.540
between `#+BEGIN_VERSE` and `#+END_VERSE`.

02:29.540 --> 00:02:33.276
You can see we've created an overlay

00:02:33.277 --> 00:02:35.700
from position 74 to 224.

NOTE Adding properties

02:35.700 --> 00:02:38.063
Now we can take that overlay that we already created

00:02:38.064 --> 00:02:41.211
and add a property, in this case a `face` property,

00:02:41.212 --> 00:02:43.540
to change the appearance of the text.

02:43.540 --> 00:02:46.279
This is a poem, and it's currently using

00:02:46.280 --> 00:02:48.083
a face that is monospaced,

00:02:48.084 --> 00:02:50.491
and so it looks like a computer program,

00:02:50.492 --> 00:02:51.900
even though it's a poem.

02:51.900 --> 00:02:54.585
I think it would be nicer to use something

00:02:54.586 --> 00:02:57.980
with variable-width font, maybe with some serifs.

02:57.980 --> 03:01.140
So let's give that a try.

03:01.140 --> 03:03.700
Now you can see that the poem looks quite a bit different.

03:03.700 --> 03:10.940
It looks more like what we'd see in a book.

NOTE Deleting an overlay

03:10.940 --> 03:13.100
We can also delete overlays.

03:13.100 --> 03:15.140
So I've named this one.

03:15.140 --> 00:03:17.765
So we can just go down and run `delete-overlay`

00:03:17.766 --> 00:03:20.048
and get rid of it, and it'll go back to

00:03:20.049 --> 00:03:22.660
the appearance it had before.

03:22.660 --> 03:23.660
And there it is.

03:23.660 --> 03:24.660
It's back to normal.

NOTE Setting fonts the right way

03:24.660 --> 00:03:28.473
Now, if you're interested in changing all of the verses

00:03:28.474 --> 00:03:31.108
inside an Org Mode file to a different face

00:03:31.109 --> 00:03:32.785
or a different font family,

00:03:32.786 --> 00:03:35.060
this isn't the way you'd really do it.

03:35.060 --> 03:37.520
I'll just show you that real quick.

03:37.520 --> 00:03:43.471
The right way is probably to change the `org-verse` face,

00:03:43.472 --> 00:03:48.868
which is the face used for all of the verse blocks

00:03:48.869 --> 00:03:51.620
inside your Org Mode file.

03:51.620 --> 03:55.100
And so this is how you do it here:

03:55.100 --> 03:56.100
`face-remap-add-relative`.

03:56.100 --> 03:58.340
Let's give it a try.

03:58.340 --> 03:59.340
It worked!

NOTE More properties

03:59.540 --> 00:04:01.805
There are more advanced things that you can do

00:04:01.806 --> 00:04:03.300
other than just changing fonts.

04:03.300 --> 00:04:05.543
There's a whole long list of them in the manual,

00:04:05.544 --> 00:04:12.580
but let's talk about the ones we're going to use today.

NOTE Visibility

04:12.580 --> 04:17.380
You can make text invisible, just like `org-present` did.

04:17.380 --> 04:21.820
The simplest way is to set the `invisible` property to true,

04:21.820 --> 04:24.500
so here's a code snippet that will do that.

04:24.500 --> 00:04:26.159
What we're going to do is

00:04:26.160 --> 00:04:28.966
go and find the word "plums" inside the poem,

00:04:28.967 --> 00:04:31.284
and then we're going to make it invisible

00:04:31.285 --> 00:04:33.436
by creating an overlay that covers it,

00:04:33.437 --> 00:04:36.820
and then setting the invisible property to true.

04:36.820 --> 04:37.940
Boom!

04:37.940 --> 04:38.940
It's gone.

04:38.940 --> 04:39.940
We've eaten the plums.

04:39.940 --> 04:42.180
Visibility is a huge topic and very complicated.

04:42.180 --> 04:44.220
There are powerful mechanisms for using it.

04:44.220 --> 00:04:46.626
I suggest reading the manual

00:04:46.627 --> 00:04:49.780
if you'd like to know more about that.

NOTE Adding text

04:49.780 --> 00:04:52.117
Another thing we can do with properties

00:04:52.118 --> 00:04:54.980
is to add text either before or after an overlay.

04:54.980 --> 00:04:57.347
Since we've made the word "plums" invisible,

00:04:57.348 --> 00:05:00.574
or anything that you make invisible in the buffer,

00:05:00.575 --> 00:05:02.662
if you add text then afterwards,

00:05:02.663 --> 00:05:05.700
it looks like you've replaced the original words

05:05.700 --> 05:08.220
with new words.

05:08.220 --> 00:05:12.046
So let's add a property, a `before-string` property,

00:05:12.047 --> 00:05:14.193
to the overlay that we used before

00:05:14.194 --> 00:05:17.137
to make it seem as though we're eating cherries

00:05:17.138 --> 00:05:18.180
instead of plums.

05:18.180 --> 05:19.180
Boom!

05:19.580 --> 05:22.020
There it is.

05:22.020 --> 05:27.820
So that's how you can replace words using overlays.

NOTE Custom properties

05:27.820 --> 00:05:29.760
You can also have custom properties

00:05:29.761 --> 00:05:31.700
that you name and then use yourself.

05:31.700 --> 05:35.320
For example, you can use it to mark regions in the buffer.

05:35.320 --> 00:05:38.008
You can also use it to add information

00:05:38.009 --> 00:05:41.180
to regions in the buffer for your own tracking

05:41.180 --> 05:45.380
in a minor mode or something like that, which we will use.

NOTE Notes on properties

05:45.380 --> 05:49.620
Finally, two notes on properties.

05:49.620 --> 00:05:51.950
We've been talking about overlay properties,

00:05:51.951 --> 00:05:54.540
but there's also something called text properties.

05:54.540 --> 05:57.460
Text properties are attached to text in a buffer.

05:57.460 --> 06:00.900
When you copy that text, the properties come along with it.

06:00.900 --> 00:06:03.056
If you modify the properties,

00:06:03.057 --> 00:06:05.500
the buffer is considered modified.

06:05.500 --> 06:08.460
Org Mode makes heavy use of text properties,

06:08.460 --> 00:06:11.677
as we can see by running this little code snippet here,

00:06:11.678 --> 00:06:14.060
which is going to tell us the properties

06:14.060 --> 00:06:16.565
and the string attached

00:06:16.566 --> 00:06:20.740
to the "Some poetry" headline on the right.

06:20.740 --> 06:23.660
There's also some controversy regarding performance.

06:23.660 --> 00:06:25.520
It may be that text properties

00:06:25.521 --> 00:06:27.860
perform better than overlay properties,

06:27.860 --> 00:06:28.892
so do some research

00:06:28.893 --> 00:06:31.060
if you're going to make heavy use of them.

06:31.060 --> 06:36.100
I prefer overlays because they're just easier to use.

NOTE Improving C++ compiler output

06:36.100 --> 06:37.540
C++ compiler output.

06:37.540 --> 00:06:41.170
So my day job is C++ programmer,

00:06:41.171 --> 00:06:46.560
and although I've been an Emacser for many years,

00:06:46.561 --> 00:06:52.860
it can be a little bit of a chore dealing with errors.

06:52.860 --> 00:06:55.680
The error messages that come out of the compiler

00:06:55.681 --> 00:06:57.580
can be pretty hard to understand.

06:57.580 --> 00:07:00.537
This has often been a barrier,

00:07:00.538 --> 00:07:04.640
particularly for people who are new to C++.

07:04.640 --> 07:09.040
So let's see what that's like.

07:09.040 --> 00:07:10.559
I have an example

00:07:10.560 --> 00:07:14.780
which is generously supplied by Ben Deane of Intel.

07:14.780 --> 00:07:17.082
So let's see what it looks like

00:07:17.083 --> 00:07:19.313
when you compile a C++ program

00:07:19.314 --> 00:07:24.400
that has a difficult error in it.

07:24.400 --> 07:27.400
Okay.

07:28.400 --> 07:31.400
Okay.

07:31.400 --> 07:35.680
So you see we have a lot of fairly verbose messages.

07:35.680 --> 07:39.400
The most verbose one I think is probably here.

07:39.400 --> 07:41.000
This one here.

07:41.000 --> 07:42.000
These are pretty bad.

07:42.000 --> 07:43.000
I think there might be bigger ones.

07:43.000 --> 00:07:43.720
Oh, yeah. Here we go.

00:07:43.721 --> 00:07:44.960
Here's my favorite one.

00:07:44.961 --> 00:07:51.063
You can see... Let's look for specialization... Basically,

00:07:51.064 --> 00:07:55.178
this whole section of the buffer here,

00:07:55.179 --> 00:07:58.228
that is specifying the specific types

00:07:58.229 --> 00:08:02.000
that a function template was instantiated with.

08:02.000 --> 08:04.000
And it's a lot there.

08:04.000 --> 00:08:05.473
So if you're trying to figure out

00:08:05.474 --> 00:08:06.817
what's wrong with your program

00:08:06.818 --> 00:08:08.884
and you're looking at something like this,

00:08:08.885 --> 00:08:11.000
it can be really, really hard to understand.

08:11.000 --> 08:12.000
Okay.

08:12.000 --> 08:17.680
Back to our presentation.

NOTE The problem with C++ error messages

08:17.680 --> 00:08:20.063
So it's often this way in C++

00:08:20.064 --> 00:08:23.400
because we compose types from other types.

08:23.400 --> 00:08:26.216
They can be long to begin with,

00:08:26.217 --> 00:08:30.240
but then a couple of other factors come into play.

NOTE Many standard class templates have default arguments

08:30.240 --> 08:33.280
First of all, we can have default template arguments.

08:33.280 --> 00:08:35.363
These are arguments you didn't write,

00:08:35.364 --> 00:08:37.008
but that are implicitly there

00:08:37.009 --> 00:08:38.325
and can sometimes refer

00:08:38.326 --> 00:08:40.300
to the arguments that you did write,

00:08:40.301 --> 00:08:42.440
which causes them to get a bit bigger,

00:08:42.441 --> 00:08:47.520
such as these allocator arguments here and here.

NOTE Some types are aliases for longer things, too

08:47.520 --> 08:49.360
Then there are type aliases.

08:49.360 --> 00:08:54.014
For example, `std::string` here expands to

00:08:54.015 --> 00:08:58.320
a type with three template arguments.

08:58.320 --> 00:09:01.940
So you can imagine, when we combine

00:09:01.941 --> 00:09:04.733
those two things together,

00:09:04.734 --> 00:09:09.763
our simple vector of maps from strings to ints

00:09:09.764 --> 00:09:14.257
becomes this humongous thing here, which...

00:09:14.258 --> 00:09:17.360
Let's run the comparison.

09:18.360 --> 09:20.960
Yeah.

NOTE Reporting type information accurately means long lines

09:20.960 --> 00:09:24.924
So in summary, to properly understand an error

00:09:24.925 --> 00:09:27.370
when you're a C++ programmer

00:09:27.371 --> 00:09:29.718
requires knowing the exact types

00:09:29.719 --> 00:09:32.280
that were supplied to your function.

09:32.280 --> 00:09:34.430
And types are built recursively,

00:09:34.431 --> 00:09:36.646
and therefore the types can--

00:09:36.647 --> 00:09:40.513
the correct exact name for the type

00:09:40.514 --> 00:09:42.776
can just be really huge

00:09:42.777 --> 00:09:46.360
and have many levels and layers to it.

09:46.360 --> 00:09:48.113
So when I was trying to understand

00:09:48.114 --> 00:09:49.466
the things I'd done wrong,

00:09:49.467 --> 00:09:52.401
especially when I was a newer C++ programmer,

00:09:52.402 --> 00:09:54.570
but honestly still even recently,

00:09:54.571 --> 00:09:57.440
if I was having a really intractable problem,

09:57.440 --> 00:10:00.123
I would just copy the entire error message out,

00:10:00.124 --> 00:10:01.735
stick it in the scratch buffer,

00:10:01.736 --> 00:10:03.649
and then manually reformat it

00:10:03.650 --> 00:10:05.563
so I could see what it was telling me

00:10:05.564 --> 00:10:07.261
I'd actually called the function

00:10:07.262 --> 00:10:09.320
or whatever it was with, the exact type.

10:09.320 --> 00:10:11.311
I had to sit there

00:10:11.312 --> 00:10:13.240
and go through the whole thing.

10:13.240 --> 10:15.240
But there's a better way.

10:15.240 --> 10:18.240
Now, anyway.

NOTE Emacs can help - Treat C++ type names as just another kind of balanced expression

10:18.240 --> 10:23.960
So what can Emacs do to help us with this problem?

10:23.960 --> 00:10:28.870
First of all, if you think about a type name,

00:10:28.871 --> 00:10:33.080
it's a lot like what we call S-expressions

10:33.080 --> 10:35.480
or balanced expressions.

10:35.480 --> 10:38.400
Lisp code itself is an S-expression.

10:38.400 --> 00:10:41.464
It's basically things with parentheses

00:10:41.465 --> 00:10:44.214
and little atoms or symbols in it,

00:10:44.215 --> 00:10:46.520
or strings or numbers.

10:46.520 --> 00:10:50.231
But parenthesized balanced expressions

00:10:50.232 --> 00:10:55.800
are things that Emacs was actually built to deal with.

10:55.800 --> 00:10:58.944
They were... I found an old manual from 1981,

00:10:58.945 --> 00:11:02.160
and the two major modes that they recommended

11:02.160 --> 00:11:05.765
or that they actually documented in the manual were

00:11:05.766 --> 00:11:08.400
one, assembly language, and two, Lisp.

11:08.400 --> 00:11:10.652
They mentioned that there were other modes,

00:11:10.653 --> 00:11:12.700
but they didn't say anything about them.

11:12.700 --> 00:11:14.625
So Lisp is something

00:11:14.626 --> 00:11:17.440
with a really long history with Emacs.

11:17.440 --> 00:11:19.976
Balanced expressions and manipulating them

00:11:19.977 --> 00:11:21.434
and doing them efficiently

00:11:21.435 --> 00:11:24.155
is just a thing that Emacs knows how to do,

00:11:24.156 --> 00:11:25.640
and Emacs is good at it.

11:25.640 --> 00:11:27.705
There's just a legacy

00:11:27.706 --> 00:11:31.320
of algorithms and functions for doing it.

11:31.320 --> 00:11:33.182
So we take types,

00:11:33.183 --> 00:11:37.839
and we take the angle brackets in the types,

00:11:37.840 --> 00:11:40.840
and we get the symbols right.

11:40.840 --> 00:11:41.814
Then we can treat them

00:11:41.815 --> 00:11:44.312
as though they were balanced expressions or S-expressions,

00:11:44.313 --> 00:11:49.320
the same kind that Emacs is really good at handling.

NOTE Add overlays to improve readability

11:49.320 --> 00:11:51.979
Secondly, we can use overlays

00:11:51.980 --> 00:11:55.260
to improve the readability of errors.

11:55.260 --> 00:11:58.012
We can take long lines and break and indent them

00:11:58.013 --> 00:12:00.160
using `before-string`s, so the same thing

12:00.200 --> 12:03.440
I used to add "cherries" into the poem.

12:03.440 --> 00:12:06.611
We can use that to insert new lines

00:12:06.612 --> 00:12:08.725
followed by indentation

00:12:08.726 --> 00:12:15.160
and produce a much nicer-looking listing of a type.

12:15.160 --> 00:12:19.641
We can also use the `invisible` property

00:12:19.642 --> 00:12:22.400
to hide unwanted detail.

NOTE Create a minor mode that runs during compilation

12:22.400 --> 12:24.960
Last of all, we can create a minor mode.

12:24.960 --> 00:12:27.854
When we're compiling things in Emacs,

00:12:27.855 --> 00:12:30.140
we often use `compilation-mode`.

12:30.140 --> 00:12:32.097
`compilation-mode` allows you to install

00:12:32.098 --> 00:12:33.553
compilation filters that run

00:12:33.554 --> 00:12:36.434
when the compiler is producing output,

00:12:36.435 --> 00:12:39.980
and at that time, then, we can add our overlays.

12:39.980 --> 00:12:42.868
We can also add in minor-mode commands

00:12:42.869 --> 00:12:45.757
that do whatever we want to the keymap.

00:12:45.758 --> 00:12:48.321
In this case, we're going to show and hide

00:12:48.322 --> 00:12:50.176
lower-level details interactively

00:12:50.177 --> 00:12:53.906
so that we can see a simplified version

00:12:53.907 --> 00:12:59.500
or a more detailed version of a type, depending on our needs.

NOTE Parsing types as balanced expressions

12:59.500 --> 13:03.980
First of all, parsing types as balanced expressions.

13:03.980 --> 00:13:05.686
We need to be able to quickly locate

00:13:05.687 --> 00:13:07.162
the boundaries and the contents

00:13:07.163 --> 00:13:08.500
of parenthesized expressions,

13:08.500 --> 13:12.100
or in this case, expressions in angle brackets.

13:12.100 --> 00:13:14.995
We use a syntax table inside Emacs

00:13:14.996 --> 00:13:18.800
to allow movement functions like `forward-list`

00:13:18.801 --> 00:13:21.100
to jump between matching angle brackets.

13:21.100 --> 13:23.460
By default, they're just parentheses.

13:23.460 --> 13:25.900
First of all, let's look at our syntax table.

13:25.900 --> 00:13:29.189
We're going to add here syntax entries

00:13:29.190 --> 00:13:33.900
to handle angle brackets as though they were parentheses.

13:33.900 --> 00:13:37.247
Then we have a lot of types

00:13:37.248 --> 00:13:42.980
that have colons in them, and those are namespaces in C++.

13:42.980 --> 00:13:45.766
By default, Emacs does not recognize them

00:13:45.767 --> 00:13:49.134
as parts of symbols, so we're going to tell Emacs

00:13:49.135 --> 00:13:52.839
that a colon is something called a symbol constituent,

00:13:52.840 --> 00:13:54.860
that it can be part of a name.

13:54.860 --> 00:13:57.613
Once we do that, then we can use our functions

00:13:57.614 --> 00:13:59.442
like `forward-list`, `backward-word`,

00:13:59.443 --> 00:14:03.288
all of the navigation and movement functions that we have

00:14:03.289 --> 00:14:06.623
that do things, that do more complicated things

00:14:06.624 --> 00:14:08.707
like S-expressions and so on,

00:14:08.708 --> 00:14:11.485
can be used now with our angle brackets

00:14:11.486 --> 00:14:16.100
and inside of our types.

NOTE Indent and fill with overlays - Use ancient "pretty printing" algorithms"

14:16.100 --> 00:14:18.462
The next thing we can do is

00:14:18.463 --> 00:14:21.540
perform indent and fill with overlays.

14:21.540 --> 00:14:23.735
We're going to use `before-string` properties

00:14:23.736 --> 00:14:25.630
to break lines and create indentation

00:14:25.631 --> 00:14:28.900
to make the output look a little better.

14:28.900 --> 14:35.320
Today, we fill mostly text and we indent mostly code.

14:35.320 --> 00:14:37.307
We fill text in order to prevent it

00:14:37.308 --> 00:14:39.902
from running off the side of the right margin,

00:14:39.903 --> 00:14:43.940
and we indent code to line up syntactic elements.

14:43.940 --> 14:47.080
Back in the day, they had algorithms that could do both.

14:47.080 --> 14:52.260
Those are what we're going to leverage.

NOTE Overlays can mimic line breaks and indentation

14:52.260 --> 00:14:54.582
We can use the `before-string` property

00:14:54.583 --> 00:14:57.760
to insert a new line in the correct number of spaces

14:57.760 --> 15:00.240
to emulate indentation.

15:00.240 --> 00:15:03.525
As a simplified example, here's some code

00:15:03.526 --> 00:15:07.280
that will indent 4 upon each open angle bracket.

15:07.280 --> 15:14.520
Let's give it a try.

NOTE Hiding details - Marking depths with overlays

15:14.520 --> 15:18.280
The next thing we're going to need to do is hide details.

15:18.280 --> 00:15:22.688
So we have nested types, and the user is going to want to

00:15:22.689 --> 00:15:27.371
be able to reveal lower-level or hide lower-level parts

00:15:27.372 --> 00:15:30.131
of the nested type interactively

00:15:30.132 --> 00:15:35.480
once we've already reformatted the error messages.

15:35.480 --> 15:40.440
Let's see how we can do that using invisible properties.

15:40.440 --> 00:15:43.992
The first thing we're going to do is

00:15:43.993 --> 00:15:46.680
mark depths within the type.

15:46.680 --> 00:15:49.328
When we're originally analyzing and formatting

00:15:49.329 --> 00:15:51.920
and doing the indentation and the line breaks,

15:51.920 --> 00:15:55.071
at the same time, we're going to go through

00:15:55.072 --> 00:15:58.817
and mark the nested levels inside the type names,

00:15:58.818 --> 00:16:00.840
just as this diagram shows.

16:00.840 --> 00:16:03.573
So depth 1, for example, will be everything

00:16:03.574 --> 00:16:06.120
inside the first level of angle brackets.

16:06.120 --> 00:16:09.038
Depth 2 will be everything inside the second level,

00:16:09.039 --> 00:16:09.600
and so on.

16:09.760 --> 00:16:12.070
And then later on, when the users request it,

00:16:12.071 --> 00:16:16.303
we can go and look at the depth that they've selected

00:16:16.304 --> 00:16:19.360
and then mark those sections invisible.

16:19.360 --> 16:20.520
Let's see how that might work.

16:20.520 --> 00:16:24.022
First of all, let's delete the overlays

00:16:24.023 --> 00:16:28.400
that we already have that created the indentation.

16:28.400 --> 00:16:32.419
Now we're going to go and do that marking

00:16:32.420 --> 00:16:35.740
with the custom depth properties here.

16:35.740 --> 00:16:38.760
To prove that I didn't pull a fast one,

00:16:38.761 --> 00:16:42.082
let's go and see what `describe-char` tells us

00:16:42.083 --> 00:16:44.660
about the depths inside here.

16:44.660 --> 16:46.460
Let's start here.

16:46.460 --> 16:52.820
Okay, so inside this part here, `std::string`,

16:52.820 --> 16:54.980
There are two overlays.

16:54.980 --> 00:16:57.780
One of them is of depth 1, and the other is of depth 2,

00:16:57.781 --> 00:17:00.601
which makes sense, because depth 1 is going to be

00:17:00.602 --> 00:17:02.011
from about here to here,

00:17:02.012 --> 00:17:07.660
and depth 2 is going to be from about here to this area.

17:07.660 --> 00:17:10.829
So it's reasonable that there should be two,

00:17:10.830 --> 00:17:12.660
and that's what we expect.

NOTE Hiding to a target depth

17:12.660 --> 00:17:17.353
Now that we've marked the nested types with their depths,

00:17:17.354 --> 00:17:21.380
let's experiment with hiding details.

17:21.380 --> 00:17:26.773
This fragment of code takes a user-supplied depth,

00:17:26.774 --> 00:17:29.085
in this case 2, and will hide,

00:17:29.086 --> 00:17:30.875
based on those markings

00:17:30.876 --> 00:17:33.932
that we've already made on the overlays,

00:17:33.933 --> 00:17:36.020
the custom depth properties.

17:36.020 --> 17:40.020
We'll take those and apply your requested level of detail.

17:40.020 --> 17:42.020
So let's try it out.

17:42.020 --> 17:43.020
Depth 2.

17:43.020 --> 00:17:46.005
All right, that hid everything under the `std::map`,

00:17:46.006 --> 00:17:47.260
so the deepest level.

17:47.260 --> 17:52.140
If we make it 1, we should get a level higher than that.

17:52.140 --> 17:54.540
So now level 1 and below are hidden.

17:54.540 --> 17:59.660
Now if we put it back to 3, it should reveal everything.

17:59.660 --> 18:04.900
So that's what we're going to use in our minor mode.

NOTE Demo

18:04.900 --> 18:05.900
Let's have a demo.

18:05.900 --> 00:18:08.538
We're going to revisit the initial example

00:18:08.539 --> 00:18:10.380
with the minor mode installed.

18:10.380 --> 00:18:12.101
Now we're going to have a compilation filter

00:18:12.102 --> 00:18:13.593
that will run on every chunk of output

00:18:13.594 --> 00:18:15.780
produced by the compiler.

18:15.780 --> 00:18:17.849
It's going to add those overlays

00:18:17.850 --> 00:18:20.420
with the line breaks and the indentation.

18:20.420 --> 00:18:22.206
It's also going to add overlays

00:18:22.207 --> 00:18:23.880
that mark up the nested types

00:18:23.881 --> 00:18:26.220
with the depths for each region.

18:26.220 --> 18:31.580
Let's add the hook for `tspew-mode`.

18:31.580 --> 18:37.220
And now we can compile again.

18:38.220 --> 00:18:41.503
All right, we can already see

00:18:41.504 --> 00:18:47.195
that these things are formatted a little bit better

00:18:47.196 --> 00:18:49.180
than they were before.

18:49.180 --> 18:50.180
They're not all on one line.

18:50.180 --> 18:53.580
Things are getting kind of lined up here.

18:53.580 --> 19:05.620
Here's a good example.

19:05.620 --> 00:19:08.637
And here's our big ugly one from before

00:19:08.638 --> 00:19:10.900
with all the characters in it.

19:10.900 --> 19:14.500
Let's try hiding some of this information.

19:14.500 --> 00:19:17.431
We'll just slowly decrease the level of detail

00:19:17.432 --> 00:19:19.740
and you can see how it works.

19:19.740 --> 00:19:22.333
Over here, where there's these ellipses

00:19:22.334 --> 00:19:25.460
next to string constant, the "..." there,

19:25.460 --> 00:19:30.386
that's where we are starting to hide information

00:19:30.387 --> 00:19:32.900
and go to the next level.

19:32.900 --> 19:36.460
Hiding more, hiding more, hiding more.

19:36.460 --> 19:38.220
Now we can go back and start adding it back.

19:38.220 --> 00:19:42.736
You can see here now we just have about four layers,

00:19:42.737 --> 00:19:45.540
which is a lot easier to understand.

19:45.540 --> 00:19:47.733
And if we start understanding what it is

00:19:47.734 --> 00:19:52.180
and we need more detail, we can just increase detail again.

19:52.180 --> 00:19:55.402
And every time we increase or decrease detail,

00:19:55.403 --> 00:19:58.900
it reformats so it still stays kind of consolidated

19:58.900 --> 19:59.900
and nice looking.

19:59.900 --> 20:01.980
Let's increase it a little bit more.

20:02.060 --> 20:04.540
Okay, so you can see how that worked.

20:04.540 --> 20:08.340
Let's go back to our presentation.

20:08.340 --> 20:10.220
All right.

NOTE Conclusion

20:10.220 --> 00:20:12.996
In conclusion, we saw how we could solve

00:20:12.997 --> 00:20:15.367
a real problem for C++ programmers

00:20:15.368 --> 00:20:18.534
by combining several Emacs features: overlays,

00:20:18.535 --> 00:20:20.489
compilation mode extensions,

00:20:20.490 --> 00:20:25.700
and balanced expression navigation using syntax tables.

20:25.700 --> 00:20:27.978
Emacs is often compared unfavorably

00:20:27.979 --> 00:20:31.460
to newer IDEs and editors with slicker user interfaces.

20:32.220 --> 00:20:36.386
What Emacs has that they don't is powerful abstractions,

00:20:36.387 --> 00:20:38.862
tons of libraries, and decades of work

00:20:38.863 --> 00:20:42.100
by some of the luminaries in the field of software.

20:42.100 --> 00:20:45.343
I think that this project would have been much harder to do

00:20:45.344 --> 00:20:48.020
in a prettier but less powerful environment.

20:48.020 --> 20:50.860
In short, there's plenty of hope for Emacs.

20:50.860 --> 20:51.220
Thank you.