From 4a7f1259da03ee30c4b30df8b8229d7dc8f55fb7 Mon Sep 17 00:00:00 2001 From: EmacsConf Date: Sat, 2 Dec 2023 13:00:19 -0500 Subject: Automated commit --- ...diagnostics-with-overlays--jeff-trull--main.vtt | 1319 ++++++++++++++++++++ 1 file changed, 1319 insertions(+) create mode 100644 2023/captions/emacsconf-2023-overlay--improving-compiler-diagnostics-with-overlays--jeff-trull--main.vtt (limited to '2023/captions/emacsconf-2023-overlay--improving-compiler-diagnostics-with-overlays--jeff-trull--main.vtt') diff --git a/2023/captions/emacsconf-2023-overlay--improving-compiler-diagnostics-with-overlays--jeff-trull--main.vtt b/2023/captions/emacsconf-2023-overlay--improving-compiler-diagnostics-with-overlays--jeff-trull--main.vtt new file mode 100644 index 00000000..9c948e2b --- /dev/null +++ b/2023/captions/emacsconf-2023-overlay--improving-compiler-diagnostics-with-overlays--jeff-trull--main.vtt @@ -0,0 +1,1319 @@ +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 defalut 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. -- cgit v1.2.3