02:37.440 Q: Do you know if PGmacs works with TRAMP?
04:38.240 Q: How did you come up with this brilliant idea?
09:26.920 TRAMP continued
13:22.966 Q: Is sqlite-mode also capable of all of this functionality (table relations, etc)? If not, will it be possible to abstract out this functionality from pgmacs somehow?
15:06.511 Q: Would it be possible to move it into Emacs tree? Are the maintainers interested in it?
16:53.850 Q: What do you use for the in-buffer tables? Vtable?
18:16.640 Integrating with Emacs 30?
PGmacs provides an Emacs-based browsing and
editing interface for the PostgreSQL DBMS. It
allows you to browse the contents of database
tables, in paginated mode for large tables, to
edit column values in the minibuffer or using a
widget-based interface, to delete, copy and insert
new rows, and to save the contents of a table in
CSV or JSON format. You can run shell commands on
column values. You can also rename tables and
columns, add SQL comments, and generate SchemaSpy
diagrams.
PGmacs works both in the terminal and in GUI mode.
It uses the pg-el library, which implements the
PostgreSQL wire protocol, to connect to PostgreSQL
over the network or over a Unix socket.
The talk will provide an overview of the functionality of PGmacs, then show how it can be easily
extended to display images stored as database BLOBs inlined in a row-list buffer.
Eric Marsden developed his first Emacs packages
pg-el, coffee.el (an implementation of the
essential Hyper Text Coffee Pot Control Protocol)
and ipp.el as a procrastination exercise to avoid
working on his PhD. He continues to use Emacs Lisp
in his spare time.
Discussion
Questions and answers
Q: This is brilliant, thank you! Do you know if PGmacs works with
TRAMP? I often use TRAMP multi-hop to access databases - both
remotely when accessing via a 'bastion server' and locally when
using OCI containers
A: There is no TRAMP support, I'm afraid. PGmacs is directly
connecting to the database server over the network. You can set
up ssh tunnels, but that would be done separately from Tramp.
Thanks
you can tunnel arbitrary data over ssh
ssh subsystems are the thing to look at, I
think... I might look at it
(sftp works that way: basically you can put
arbitrary progams at the remote end... like, oh, say,
pgsql. transparently to the ssher.)
Possibly PGmacs could setup the tunnel itself,
using TRAMP?
With docker.el, kubel, etc, it's often possible to for example
select a container/pod/whatever that is hosted on a machine
you've connected to via TRAMP (such as
/podman:\<image>:/path/), and trigger a terminal/eshell as well
as port-forwards and other similar things. It'd be nice to be
able to use this tool in a similar way since it would open up
the ability to use it with complex connection configurations.
Doing SSH tunnels manually is ofc totally fine in practice
Q: \<Donovan>Great work! I'm impressed. How did you come up with
this brilliant idea?
A: First got the idea by looking at sqlite-mode
Q: Is sqlite-mode also capable of all of this functionality (table
relations, etc)? If not, will it be possible to abstract out this
functionality from pgmacs somehow?
A: I'm not veyr familiar with sqlite-mode but it looks more
basic. There are differences between the sql dialects so it will
be difficult to abstract it out.
Q: Would it be possible to move it into Emacs tree? Are the
maintainers interested in it?
A: Currently its at a very early stage and is being updated
regularly. I also have some philosophical reasons to not do it
regarding copyright transfer to the FSF.
Q: Almost missed this one, so glad I didn't, but this may have been
answered already: what do you use for the in-buffer tables? vtable?
A: vtable but "forked" (some changes/improvements, may
consider "merging" back with vtable core work)
Q:
A:
Notes
I have got 270 tables, and it stays there forever "loading"
tables, and nothing appears.
Thanks for checking it out! You may have an authentication failure,
and PGmacs is not very good at showing that in the connect phase.
Switch to the *Messages* buffer and see whether there's an error
message there.
This is happening with me as well. I noticed this error message
in Postgres Logs. It works if I open the postgres database.
db-1 | 2024-12-08 18:58:41.524 UTC [48] STATEMENT:
CREATE EXTENSION IF NOT EXISTS vector
db-1 | 2024-12-08 18:59:13.831 UTC [50] ERROR: could
not open extension control file
"/usr/share/postgresql/14/extension/vector.control": No
such file or directory
In *Messages* buffer, this is what I see
pg-bind: Wrong type argument: stringp, 97
OK, thanks for this feedback. It looks like your Postgres vector
extension is not well set up, but that really shouldn't be causing
a complete connection failure. You can comment out the line
(pg-vector-setup con) in function pgmacs-open in pgmacs.el and see
whether that helps
Let me try that and report back.
I got this error: pg-do-startup: Process postgres not
running: failed with code 111
OK, that means that the network connection failed. There is
probably more error information in the backtrace
Ah sorry, had stopped the pg. This time I got the same error
pg-bind: Wrong type argument: stringp, 97
But it didn't try to load vector extensions (from pg logs).
OK, thanks for that backtrace. I don't immediately see what
is wrong here. There is something strange about that
shared_urls table, it seems. Are you using pg-el from the
github repo?
Hi, this is a short presentation about PGmacs,which is a browsing and editing interface forPostgres databases.My name is Eric Marsden, and I'm thedeveloper of this Emacs Lisp library.PGmacs was inspired by sqlite-mode, which is agreat feature available from Emacs 29 onwards.It allows you to view and modify SQLitedatabases you might have lying around.It's a really great feature.It would be even better, however, if itwere able to use a real database.And I happen to know that was possiblebecause a few years ago, I wrote anEmacs Lisp library, pg.el, which implements the wireprotocol used for communication over the network betweena Postgres client and the Postgres backend, thePostgres server.I've included here an example of what itlooks like to use this library.You connect to the database by specifying thedatabase name, your username, your password, potentially thehostname that you're connecting to.Once you're connected, you can then execute SQLstatements, for example, to create a new table,to insert values into that table, and tocount the number of rows in a table.And pg.el does automatic type conversion toand from Emacs Lisp types and Postgres types foryou.
Probably the best is to jump straight intoa demo of PGmacs.When we connect to a database, we seeup the top of the buffer, some informationabout the backend that we're connected to, someversion information and the total database size ondisk.There are some shortcuts to some commands wecan run on the database, and there's alist of tables that we have access to,with again, metainformation about their size ondisk and their owner.Now, we can enter a table by pressingreturn.Here we again see some metainformation aboutthe table, such as the list of columns,the SQL type of each column, any defaultsthat might be present and any SQL constraints.We see any indexes that might be presenton this table, and then we see thelist of rows of data in the table.If we see any information which is incorrector incomplete, we can easily fix it bypressing enter again, and this updates the informationpresent in the database.PGmacs shows us this in the minibufferit has updated one row.We can look at help for the keybindings that are present in this type ofbuffer.If we scroll down, we can see thatwe can upcase the value of a cellwith M-u.Let's try that out.Okay, here we have updated the value ofthe cell in the database.We can now lowercase it, and we canput it back to the initialtitle case of the value.We can also run a shell command ona cell value, to count the number ofcharacters, for example.We can run a shell command with aprefix argument, which updates the value in thedatabase with the output from the shell command.So that has updated the database.If we do that again, that will reversethe value. If we come backto the list of tables, we seethat there is a table which is calleddeleteme.We can try renaming this table with R,we can look at what is in thistable.
Okay, there is only one row of informationthat doesn't seem very important, so let's deletethat.Let's now delete the table with DEL.PGmacs asks for confirmation, and we've deleted thetable.Now when we have a big table witha lot of data, PGmacs is going toshow us the results paginated, so we cango chunk by chunk through the table.We can implement a where filter on therows to only show the rows that matcha certain SQL clause.So for example, here we have some temperaturemeasurements.We want to focus on measurements that aremore than 40 degrees Celsius, for example.Okay, we have now filtered on a certainnumber of rows.The filter is shown to us just uphere, and we see here that we havesome values that look anomalous.There's one, 140, and one is 61.We probably want to delete them, they representerrors.We can mark them for deletion with d,and then really delete them, expunge them, asin Dired, with x.
We can export this table in CSV format,thanks to this little button up here.Here we have our table conveniently formatted asCSV.We can also export a particular row toJSON by typing j, let's look atwhat that looks like.Okay, here's the JSON for one of therows in the table.
Now let's look at a table that containsa column of type HStore.This is a Postgres-specific key-value map.Then the attributes column is of typeJSON, which can be stored natively in Postgres.It's possible to edit these values using awidget-based interface by typing w, and herewe have a convenient interface for modifying thesetypes of values.Likewise, for the JSON type parameter, we canupdate using a widget-based interface.
Let's connect to a different database.We do that with a M-x pgmacs, andthen enter our username and password.Here we have the list of tables presentin this database.
PGmacs has some support for running the SchemaSpyutility, which generates a graphical representation of therelationships between tables in this database, which canbe useful when you're discovering the database.Here is the SVG that's output by thisutility.This is a test database containing information abouta digital media store.It has a table with information about thetracks that are available.If we look at this table, wesee that we have the name of thetrack, a reference to the album, album ID.This is a reference to a foreign key,a key in the table which is calledalbum.Now we can follow this foreign key referencesimply by pressing Enter, and here we findit's the album called For Those About ToRock.And in the same way, here we havea foreign key reference to the relevant artistwhich we can follow.That's, of course, AC/DC.
And finally, PGmacs has some convenience queries thatallows us to list the procedures which aredefined in this database.Here we have the built-in procedures, mostlyused by the PostGIS extension.We can also display some more information aboutour backend.Here we have the list of extensions whichare available.We can load one of these extensions ifwe have the rights to do that.Here we've loaded the relevant extension.We can show some information about the Postgressettings also, and update them if we havethe rights to do that.
[00:08:18.850]Emacs as an application development platform
Now I'm preaching to the converted, but Emacsis a really great application development platform.PGmacs is currently around 3000 lines of code.A first point of comparison, PGCLI, which isa text user interface for accessing Postgres implementedin Python, is 17,000 lines of code.PGAdmin4, which is a well-known Python GUIfor administrating Postgres databases, is almost half amillion lines of code.And DBeaver, implemented in Java, is almost amillion lines of code.Developing things on Emacs, you get forfree portability between different platforms.As I'm showing you, it works great onLinux, which is where I developed this library.It also works perfectly in the terminal, exceptfor some of the functionality I showed, whichrequires SVG support.It also works well, if you're into thatkind of thing, on MacOS and on Windows.And it even works perfectly on Haiku, whichis a free BeOS clone.Emacs is actually really pretty on this operatingsystem, so congratulations to the people who didthe port there.Now, of course, the main advantage of buildingon the Emacs development platform, is that theapplication is easy for the user to extend.
To illustrate that, previously we were looking ata table of temperature measurements.Imagine we want to highlight rows in thistable, which look anomalous, where the value looksa bit extreme.That's quite easy to do with a bitof Emacs Lisp.We define a function, which, if the cellvalue is bigger than 40, is going todisplay it in a face which has adark red foreground.We can now register this display function forthe measurement column in the temperatures table.And if we reopen the table now, wesee that the anomalous measurements are indeed highlightedin red.Another example, imagine we have a table whichcontains image data.There's a column which is of BYTEA type,which contains images in binary form.We can display these inline as follows.We create an inline image display function, usingEmacs' image support.And then we'd register this function to displaythe image column in the inline image table.If we now reopen the inline image table,we see the images are displayed inline.And as a final example of customisation, here'show to bind a key to a specificfunction, in the row-list buffer.Let's define a function that does a DuckDuckGolookup for a particular value inthe Emacs web browser.We can define a function which does afuncall on the cell value for thisDuckDuckGo lookup function.And finally we can define a key, thecapital D key, in the row-list map,which calls this function that does aDuckDuckGo lookup.And now if I'm browsing information in atable that I want to do a websearch on, I can use my D shortcutand see some web results concerning the cell.
So to conclude, the source and installation instructionsfor PGmacs are available on GitHub.It requires Emacs 29.There is a prebuilt container image which youcan use for testing.It's a Docker image.The Docker image only works in terminal mode.And of course that's a recommended way oftesting Emacs Lisp code that you loadinto your Emacs before having read it.It works with any recent version of Postgresover the past 10 years, including the latestrelease, Postgres 17.It does work with a certain number ofdatabases that are compatible with Postgres, such asParadeDB, TimescaleDB and IvorySQL.However, it doesn't work with all databases thatclaim to be Postgres compatible.It doesn't work, for example, with CrateDB orwith CockroachDB or some others that you seelisted here.The reason for that is that these databasesdon't implement the system tables that PGmacs queriesto obtain information about the columns present ina table, the size on disk, the ownershipof tables, etc.PGmacs supports TLS encrypted connections to the database,as well as local Unix socket connections.And in terms of stability, I would classifyit as beta status.I do use it myself in production onsome not very important data.Really, it works quite well.Thanks for your attention.
Captioner: eric
Q&A transcript (unedited)
And I believe we are live. Hi, Eric, how are you doing? Verywell, thanks. It's a pleasure to have you as one of ourspeakers but it's also very nice to see you present aboutpgmacs because I found your talk to be very didactic and veryvisual. So thank you for taking the time to do a very nicepresentation. I wanted to give the opportunity as I do withother speakers to maybe talk about some stuff that you couldnot include into the talk because of the format. So is thereanything you'd like to share with the viewers that youweren't able to include?Oh, I think I gave most of the most of the relevantinformation. This is a fairly young application. I've beendeveloping this since roughly the beginning of the year. Sothere are probably some rough edges that people will runinto if they use Postgres differently from what I do. Or theyhear maybe conflicts with some other Emacs packages thatpeople use that I don't use. So I would really welcome peopletrying it out and sending out bug reports if they doencounter some. Yeah, I mean, it's usually... Go on,please. Yeah, that would certainly help to make sure it'snice and robust. And of course, if you're letting this looseon some production database that you might have, you wantthis to be quite robust, obviously. Yeah, indeed. Becauseusually, you know, when you start publishing packages likethis, that's when you realize that it has bad interactionwith other modes in the Emacs of other persons. Butespecially when you're dealing with databases, you alsorealize that the domain space of what you're trying to dowith your mode also is hugely dependent on what people havein their database, which schema they have. So, indeed, ifyou have been interested, and I think plenty of people havebeen interested by what you've presented, part of thereason a software becomes great is that you've got plenty ofpeople making bug reports and making sure that all thefaults have been ironed out. So, you know what your task is. Iwill also ask you, particularly right now, peoplecurrently viewing, to add your questions on the pad asusual, because you've had plenty of nice reactions, but I'msure you have plenty of questions as well. So Eric, what I'llbe doing, I'll be reading you the questions so that it's alittle more didactic. Starting with the first one. This is
[00:02:37.440]Q: Do you know if PGmacs works with TRAMP?
brilliant, thank you. Do you know if pgmacs works with TRAMP?I often use TRAMP multi-hop to access databases bothremotely when accessing via bastion server and locallywhen using OCI containers. I believe you've alreadyanswered but if you could just perhaps read your answer aswell for everyone to benefit from it. Yep, sure, that's mycomment indeed. So I haven't currently implemented anyTRAMP support. I'm not sure that TRAMP is really useful forthis type of situation, because as I understand it, TRAMP isestablishing SSH connections itself to remote servers.pgmacs is doing the same thing, so it doesn't currently haveany support for hooking in with the TRAMP support. Right.Pardon me if I missed the presentation. Oh, go on, please. Iguess you could set up an SSH tunnel. It does work with an SSHtunnel, obviously, but there's no support for hooking intoan SSH tunnel that TRAMP might be able to create. I'm not sureTRAMP actually uses SSH tunnels rather than directcommands, but anyway. Yeah, I think that might be useful.Yeah, I don't know either. I don't have the answer whetherTRAMP actually can create tunnels like this. I'm usuallyused to TRAMP connecting to an endpoint, be it a directory ora file, and the tunnel is just you accessing the file. Butusually, if you're trying to access a remote Postgresdatabase, you would probably manage the port forwarding ina separate terminal just to be able to make sure thateverything maps correctly to your machine, and then youwould launch pgmacs with the forward port information.That's, I assume, how you would do it anyway. But yeah, Imean, if you could specify what you mean by TRAMP support andif you have something specific in mind, I'm talking to thequestioner, feel free to specify and we'll see if you cananswer it. But in the meantime, moving to the next question.
[00:04:38.240]Q: How did you come up with this brilliant idea?
Great work, I'm impressed. How did you come up with thisbrilliant idea, I assume, to create pgmacs? Well, thanks forthe compliment. It's a lot of fun developing somethingwhich is, as I said, such a small amount of code and whichprovides quite a bit of useful functionality. Inparticular, if you compare it with existing Terminal modeapplications for manipulating Postgres data, they arenot as extensible as Emacs is naturally. So I actually gotthe idea for developing this when I first tested out theSQLite mode, which is available in Emacs 29.1.And I thought, well, that's really quite impressive. And itallows you to delete rows and insert content and so on. And Iwas thinking, yeah, Emacs is a, is a useful environment to dothat. And since several years ago, when I was doing my PhD, soto avoid doing my PhD, I was developing Emacs, I wasdeveloping stuff in Emacs Lisp and one of the libraries Ideveloped was an interface to Postgres over the network. Sothat's the library called pg.el, which is used by pgmacs toaccess Postgres and to do all the parsing of data whicharrives in Postgres formats into the Emacs Lisp into theEmacs corresponding versions. So, for example, integersare passed as Emacs integers, floating point numbers asfloating point numbers, and so on. Right, yeah. I mean, it'spretty needed, obviously, when you have such a tooling likethis, to make sure that the type conversion works properly,because the types that you have in Postgres do notnecessarily map over to what we have in Emacs. Like, I'minterested, how would you handle g's and b columns in pgmacs?JSON is mapped to an edis dict, a dictionary.It depends on the top level object type for your JSON column.If it's an array, it's mapped to an Emacs Lisp array. If it's adict, which is most common, it's mapped to an Emacs Lispdictionary. All right, well it makes perfect sense. So I canbreak in with a question. Thanks, I just helped myself to theBBB privilege of kind of running around backstage, being ahelper backstage. So thanks for your awesome talk, Eric. Isuper appreciated it. You know, I noticed that you thatyou're on a slightly older version of Emacs that I deal within helping with producing the Windows binaries I run intoand with some other stuff I do. I'm dealing with thatfriction of sometimes I've got some work of my own thatapplies against a specific version of Emacs and it's a bunchof work to think about moving it forward. Just curious if youstarted thinking about that or if you routine, if that's aroutine that you haven't done or there's something maybespecifically going on with, you know, with trunkdevelopment that looks intimidating to deal with. Thanksfor the comment. I'm not sure I'm using a really old versionfor Windows. I don't really develop often on Windows, but I Ioccasionally check that it works, and I took a screenshotthat I included in the slides here, but I think I'm using29.4, the current version on Windows. I thought I saw 29.1,so that's probably my, I probably missed it when it went by.My bad. No, no, I use it via the choco package updater so thatupdates the Emacs version quite easily on Windows. Sothanks for your work on maintaining Windows binaries. Irealize that was- I sit downstream at the end of a lot of otherpeople's hard work and then just focus on trying to QA welland help catch problems early. It's really fun. But ofcourse, my pleasure.Coming back to the previous question, so the thequestionnaire actually provided a little more context. So
with docker.el, kubel, etc, it's often possible to, forexample, select a container pod or whatever that is hostedon the machine you've connected to via TRAMP, such asPodman, colon image colon path and trigger a terminal shellas well as pull forward on other similar things. It'd be niceto be able to use this tool in a similar way since it would openup the ability to use it with complex connectionconfiguration. Doing SSH tunnel manually is of coursetotally fine in practice and if it is actually the casepersonally when I need to remote into a kubernetes machine Iuse POSIX script that I use on most of my machines but I don'tdo it inside Emacs. But yeah, if such a thing is possible viaTRAMP, it definitely feels like it would be possible to dosomething similar in pgmacs. So perhaps that's a path ofinvestigation for you that has opened up. Yeah, thanks forthese comments. I'll look into that indeed if people havesome shortcuts registered in TRAMP. So not for a terminal,because pgmacs won't work through a terminal, but through aport forward, then that would be convenient. I'll see howeasy that is to set up. Yeah, I'm pretty sure the way it worksis that it starts some processes in the background in Emacsjust to either maintain the port forward or to maybe remapsome kubecon things or whatever. So with pgmacs,considering complex pipelines to get to the enddestination, it feels like it would be possible to dosomething. But perhaps it's not the responsibility ofpgmacs, perhaps it's the responsibility of another,perhaps something that would target TRAMP more so thanpgmacs. But it's nice to see again how the beauty of Emacsis that everything is Elisp at the end, and the way theyinteract, you might want to question yourself whether thisbelongs more to pgmacs or more to TRAMP, but at the end of theday, both applications will be able to benefit from thefunctions of the other. So that's the beauty of thephilosophy right here. I do see... Absolutely, I agree.Sorry, before we move to different questions, anadditional point. I should point out that to warn peoplethat probably running over an SSH tunnel is going to be a bitslow. I mostly use it on my own machine via a local Unixconnection. And for some reason that I haven't understood,pgmacs is quite a bit slower when it's even connecting to thesame database on the local machine, but via Emacs' networksupport instead of via the Unix socket support. There islike a factor 10 difference in throughput and in latency. Idon't really understand why currently, because it's usingexactly the same Emacs Lisp level primitives. And when youdo this using other libraries like libpq, which is thePostgres standard official library for connecting toPostgres, there's not such a performance difference. Sothere's probably something that is not working perfectlyin the Emacs network support. I'll have to see whether I caninvestigate how to improve that performance. Yeah, I'mgoing to say it sounds like a great bug to have because itfeels like it will allow you to dig deeper into Emacs tounderstand what is going on here. Because as you said,normally it's supposed to work exactly the same,especially if it's still in your local machine, but itdoesn't. Personally, that's the kind of bug that I reallylike and that I'd like to spend more time investigating. Soperhaps you might think otherwise, but I wish you luck on thedebugging with this particular matter. All right, movingto the last question that we have and then we'll probably goon a little bit of a break.
[00:13:22.966]Q: Is sqlite-mode also capable of all of this functionality (table relations, etc)? If not, will it be possible to abstract out this functionality from pgmacs somehow?
Question. Is SQLite mode alsocapable of all of this functionality, table relations,etc.? If not, would it be possible to abstract out thisfunctionality from pgmacs somehow?So I'm not very familiar with SQLite because I don't reallyuse it very much myself. I'm not sure I can answer thatquestion. Sorry about that. I think it is probably a bit morebasic because SQLite itself is quite a bit more basic interms of the types of indexes it's able to support and thetypes of constraints it's able to support. Is it relevant tocreate an abstract API for connecting to databases? I thinkthere is already actually a library that abstracts out fromSQLite and Postgres. Postgres, when you connect to it via aPSQL subsystem,it might be worthwhile doing that, but there are often a fewminor differences in SQL syntax and so on betweendatabases. So it might be difficult to have something thatreally works with generic queries in an effective way. Allthese SQL dialects are a little bit different,unfortunately. So there was another question about I wasjust going to read out the next question.
[00:15:06.511]Q: Would it be possible to move it into Emacs tree? Are the maintainers interested in it?
So have you thoughtabout integrating your work into the Emacs tree? Do you knowif people are interested? This was a question from the past.Yeah, I think it's probably a bit young to do so, so far.I'm updating it quite regularly. Maybe once it's morestabilized, I wouldn't necessarily object to this. I havesome sort of philosophical objections to giving away mycopyright, so I'm not sure that will actually be possible.Oh, that'd be interesting. I'd love to get you on maybe apanel talk about that sometime. Something I'd think about.Well, from a very simple point of view, I think that thecopyright and the system works well with the existinglicense and without a license transfer, so I don't feel thatthe, sorry, without a copyright transfer,I don't feel that the copyright transfer is really a necessary step fortaking things away from maintainers. It feels like askingthe maintainers to give up on some of their copyright...Indeed. Yeah, I see where that's a little beyond our scope,but it's a fascinating topic and I appreciate your sharingyour views there. I mean, that sounds like a whole topic ofits own, frankly.Yeah. Corwin, do you want to fill the last question? Sure. Sothe question was, I almost missed this one, so glad I didn't.This may have been answered already.
[00:16:53.850]Q: What do you use for the in-buffer tables? Vtable?
What do you use forin-buffer tables? Do you use vtable? Yep. Thanks for thequestion. It is indeed vtable. However, it's not reallyvtable. It's a fork that I made, which is called pgmix table.because Vtable doesn't have exactly the rightfunctionality in particular for recoloring rows when youadd a row. So I've currently forked this. I'm thinking aboutgiving those back as patches to Vtable, plausibly.I know that there is some ongoing work also on vTable in thecore. So I'll have to look at what is plausible to feed backinto the main version.All right, great. I think we are nearing the end of the Q&A. Weare due to move to the next talk in about three minutes now. Ican fill 30 seconds or a minute of that with I guess one moremaybe back and forth and I'll try to be quicker this time.First of all, thanks for your kind remarks. But my questionwasn't really about Windows so much, it was just how I'mrelating... So have you, let me put it more simply, have you
started looking at integrating with Emacs 30 or with themaster branch at all? Do you have any sense of how much workit's going to be for you to carry things forward there? I'vetested it with the pre-release, yes. I mean, just a verybasic testing and everything works perfectly. There'sreally no... There was no difference that I have noticedbetween 29.4 and the 30 pre-release on the aspects that I useat least in Emacs. Neato.That was it, Leo. Thanks for letting me back in for one morebite at the apple there. And I appreciate everybody tuningin and participating in the Q&A and this awesome talk.Thanks for your questions. That was great. Yeah, and thankyou for answering them and for the presentation as well. Sowe'll be moving in about two minutes to the next talk, whichis pre-recorded as well. Well, we didn't really give you thechance, Eric, to have the last word. So do you have any lastword?please try it out, try out pgmacs and send some feedbackthat'll help improve it over time. Sure, great. Well, thankyou so much, Eric, for taking the time to come to theconference, and we'll see you soon. Thank you. Bye,everyone. Bye. And we'll be live with the next talk in about 1minute 30. So we'll take a little bit of a breather, go makesome coffee, go take a bio break. We'll be back soon. See youin a bit.