Miscellaneous stuff: gedit configuration

Another thing I mentioned on G+ lately, and thought I’d throw in here: gedit configuration.

I’ve been using gedit for years in pretty much its dead stock configuration, which is more or less ‘notepad clone mode’. It’s very, very basic. You get some highlighting if you open a file it recognizes as some kind of source code or other structured format (RPM spec file, XML, HTML, etc), but that’s about it.

I was hitting bugs in gedit in Rawhide and used Geany for a bit, then when I switched back to gedit, started missing some of the more developer-ish features of Geany (since I find myself actually honest-to-god working on source code more and more these days, for my sins…and I’ve been working on RPM spec files forever, just without much in the way of convenience features).

So I poked around, and found some settings and features for gedit that I now find rather more comfortable.

Some really obvious low-hanging fruit that I’m kicking myself for not doing earlier, from Preferences:

  • Just check every damn box in View, at least that’s what I like. Line numbers, yes please! An 80 character margin, handy! Highlight matching brackets, how the hell did I live without you?
  • Editor – tab width is going to vary depending on whose code base you’re working with, but it’s easy enough to change it. Insert spaces instead of tabs, yes – apply elsewhere for an explanation of why tabs are evil, but they are. Enable automatic indentation, is kind of a personal call – sometimes it helps, sometimes it hurts. Turn on autosave if you like.
  • Plugins – there’s some interesting stuff here, like Python Console and Modelines and stuff, but the main one that’s extremely powerful but sorta hidden away is Snippets.

Snippets

Snippets I came across in geany – Christoph Wicket has a great geany configuration in his github space – and had no idea gedit had tucked away until I went looking. Turn that plugin on! You want it!

Snippets are basically just a way of inserting pre-canned text – say you’re always typing your name, you can define a snippet that contains your name, and then configure a trigger for inserting it (you can use a shortcut key combo to ‘trigger’ a snippet, or you can use a form of tab completion – e.g. typing ‘name’ then hitting tab would insert your name). Just this function is neat enough, but you can get much cleverer, because of course, since we’re talking about geeks, you get quite a powerful syntax (that page is pretty crappy, it gives you two lines of introduction then dives into head-spinny mode, but you get the idea) for doing Clever Stuff in snippets.

You can set up snippets by going to Tools / Manage Snippets…, and for a simple one, just go to Global / Add a new snippet…, type some text in the Edit: box, assign a Tab trigger and/or a Shortcut key – the Tab trigger thing is described above – optionally give your snippet a name, and close the dialog. Now use your trigger and your snippet will show up.

Pretty obviously, you can make snippets global (like the one above) or only active for particular types of file (there’s an extremely long list of types of structured files gedit distinguishes between on the left, and you can create type-specific snippets for any of them). I recreated a few of the RPM spec snippets from cwickert’s geany config that I found most useful. A lot of these are just simple text strings – mainly RPM macros like %{_bindir}, %{_libdir} and the like. I did set up one slightly clever one, though, which serves to illustrate some of the ‘clever’ features of snippets. It looks like this:

* $(date +"%a %b %d %Y") Adam Williamson <myemail@address.com> - ${1}
- ${2}

…and as you might be able to guess, it’s just a snippet for inserting an RPM changelog entry. The gedit doc page I linked to earlier makes the ‘placeholder’ concept sound crazy complex, but really a simple placeholder is just ‘a series of places you might want to manually insert text into the pre-canned snippet’, and all the other types of placeholder are different ways of inserting some kind of dynamic content – i.e., something that will be different depending on when or where or in what context you invoke the snippet.

You could try and write something very snazzy to figure out the EVR (Epoch, Version, Release) for the package from the appropriate fields – effectively re-implementing what RPM does – but I just stick a simple placeholder at the appropriate point in the snippet (that’s the ${1}) so when I insert the snippet, the next thing I do is type in the correct EVR manually.

Then obviously I can’t include the actual changelog entry in the snippet, so I have a second simple placeholder – the ${2} – for typing that. So, when I insert this snippet, the cursor shows up at the end of the first line (with a very faint grey box to indicate that it’s at a placeholder location) and I type the EVR, then I hit tab, and the cursor moves to the second line where the changelog entry goes, and I type the changelog entry, and we’re all done.

That only leaves the other clever bit: that $(date +"%a %b %d %Y"). That’s one of the simplest forms of a ‘complex’ placeholder. What that does is actually pretty simple: it’s just the way you call out to an external command and stick the result into the snippet. It runs the command date +"%a %b %d %Y" when you invoke the snippet, and stuffs the result into the snippet at that location. And what that command does is give you a date string in RPM changelog format – “Tue Jan 21 2014” or whatever.

I gave this snippet the Tab trigger clog, so when I type ‘clog’ and hit tab, I get a properly-formatted RPM changelog entry into which I just have to type the EVR and the actual changelog entry. Veeeery handy.

And that’s some gedit configuration stuff for ya! Hope it was useful. And yes, I’m extremely lame for not being some kind of emacs/vim magician by now, I know.

11 Responses

  1. Matěj Cepl
    Matěj Cepl January 24, 2014 at 2:44 am | | Reply

    I have a way more complicated script at http://luther.ceplovi.cz/git/rchi.git/tree/rchi which also adds EVR. Maybe it could be modified for your purposes (and I have agree, snippet is much more user friendly option than rewriting whole file, which is what I do).

  2. Colin Guthrie
    Colin Guthrie January 24, 2014 at 3:00 am | | Reply

    Semi-related question. What do you reckon your preference is for changlog from the Mandriva days?

    e.g. we used to (and still do in Mageia) generate the changelog bit automatically from version control history.

    Pros:
    It makes you write good/descriptive commit messages.
    Less manual work (only write the message once)

    Cons:
    If you get it wrong you have to (as we use svn) svn propedit –revprop it. In git there is no such feature so you’d have to use notes or something to “fixup” a message.
    You can swear in commit messages even if you really, really want to.

    I ask this as we’ll likely switch to git at some point in the not too distant future. I’ll have to make a call when reimplementing whether to switch to a static changelog or generate it automatically from git history + add some hack for notes.

    As someone who has worked with both schemes, which do you prefer?

    1. Matěj Cepl
      Matěj Cepl January 24, 2014 at 8:14 am | | Reply

      WHAT? There is no such thing as changing commit message in git? Wow!

      git commit –amend
      git rebase -i (command edit)
      etc.

      1. Colin Guthrie
        Colin Guthrie January 24, 2014 at 8:32 am | | Reply

        Thanks for the sarcasm!

        Amending and rebasing is fine…. if you are the only one with a clone.

        This type of fixups are NOT meant for post-push changes unless something catestrophic occurs. Otherwise anyone else making changes has to do forced rebases etc. This something you should try very hard to keep out of your git workflow when working with other people.

        This is why “git notes” were invented to be able to attach extra notes to commits after they have been pushed and shared in a way that doesn’t create divergent branches.

Leave a Reply to Matěj Cepl Cancel reply

Your email address will not be published. Required fields are marked *