25

Question code is obsolete.

But the answer code and the code linked in the comments still work.


About

This script adds Ctrl+B (bold), Ctrl+I (italic), Ctrl+K (code), and Ctrl+L (link) shortcuts to comments.

My script doesn't work exactly the same as the question/answer text editors, but it's similar. One difference is that hitting Ctrl+B when no text is selected just puts ** in the window, as opposed to putting **strong text** with "strong text" selected. This means you can use the shortcuts like you would in a word processor: hit Ctrl+B to enter bold mode, type what you want, then hit Ctrl+B again to back out. (Actually the question/answer text editors behave similar to this, but uses trickier javascript to accomplish it.)

For links, I'm using simple JS prompt() function, rather than trying to hook into the text box that is built-in for adding links questions/answers.

Download

view obsolete source (the script doesn't currently work; see the comments and answer, below.)

Change History

  • 2012-03-26: Added support for Ctrl+L
  • 2009-07-18: Initially released

Platform

Tested on Firefox 3.6 and Chrome 9.0, on Windows 7. Requires Greasemonkey on Firefox.

License

Do whatever you want, as long as you don't sell it or claim you wrote it yourself. If you make any cool modifications, let me know!

Obsolete Source

Beware that this script needs to be modified per the answer, below:

// ==UserScript==
// @name          stackoverflow comments formatting shortcuts
// @namespace     stackoverflow
// @description   Adds Ctrl+B (bold), Ctrl+I (italic), Ctrl+K (code), and Ctrl+L (link) keyboard shortcuts to comments.
// @include       http://stackoverflow.com/*
// @include       http://meta.stackoverflow.com/*
// @include       http://superuser.com/*
// @include       http://meta.superuser.com/*
// @include       http://serverfault.com/*
// @include       http://meta.serverfault.com/*
// @include       http://askubuntu.com/*
// @include       http://meta.askubuntu.com/*
// @include       http://answers.onstartups.com/*
// @include       http://meta.answers.onstartups.com/*
// @include       http://nothingtoinstall.com/*
// @include       http://meta.nothingtoinstall.com/*
// @include       http://seasonedadvice.com/*
// @include       http://meta.seasonedadvice.com/*
// @include       http://crossvalidated.com/*
// @include       http://askdifferent.com/*
// @include       http://meta.crossvalidated.com/*
// @include       http://stackapps.com/*
// @include       http://*.stackexchange.com/*
// @exclude       http://chat.stackexchange.com/*
// @exclude       http://api.*.stackexchange.com/*
// @exclude       http://data.stackexchange.com/*
// @exclude       http://area51.stackexchange.com/*
// @author        Kip Robinson - http://stackoverflow.com/users/18511/kip
// ==/UserScript==

(function(){
  function with_jquery(f) {
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.textContent = "(" + f.toString() + ")(jQuery)";
    document.body.appendChild(script);
  }; 

  with_jquery(function($) {
    $('textarea[name=comment]').live('keydown', function(e) {
      //Ctrl+[BIKL]
      if(e.ctrlKey && !e.altKey && (e.which == 66 || e.which == 73 || e.which == 75 || e.which == 76))
      {
        //all text
        var text = $(this).val();

        //text before selection
        var before = text.substring(0,this.selectionStart);

        //selectect text
        var selected = text.substring(this.selectionStart,this.selectionEnd);

        //text after selection
        var after = text.substring(this.selectionEnd,text.length);

        //length of selection
        var selLen = selected.length;

        //markup character that will go before/after section. (Note: link is handled a bit differently.)
        var markup = '';
        var isLink = false;
        if(e.which == 66)
          markup = '**';
        else if(e.which == 73)
          markup = '*';
        else if(e.which == 75)
          markup = '`';
        else
          isLink = true;

        //markup length
        var mLen = markup.length;

        //replace is what the selected text will be replaced with
        var replace = '';
        if(selLen == 0)
        {
          //nothing selected. just print the markup
          if(isLink)
          {
            var url = prompt('Please input link URL');
            var linkText = prompt('Please input link text');
            replace = '[' + linkText + '](' + url + ')';
          }
          else
          {
            replace = markup;
          }
        }
        else if(!isLink && selLen > 2*mLen
                && selected.substring(0,mLen) == markup
                && selected.substring(selLen - mLen, selLen) == markup)
        {
          //We have selected something that starts and ends with the markup. We will remove the markup in
          //this case. For example, "*sometext*" becomes just "sometext". This is not available for links.
          replace = selected.substring(mLen, selLen - mLen);
        }
        else
        {
          //we have selected something. put the markup before and after it.
          if(isLink)
          {
            var url = prompt('Please input link URL');
            replace = '[' + selected + '](' + url + ')';
          }
          else
          {
            replace = markup + selected + markup;
          }
        }

        //now update the text
        $(this).val(before + replace + after);

        if(selLen > 0)
        {
          //if something was selected, make the result selected too.
          this.selectionStart = before.length;
          this.selectionEnd = before.length + replace.length;
        }
        else
        {
          //nothign was selected, so put the cursor at the end of the updated text.
          this.selectionEnd = this.selectionStart = before.length + replace.length;
        }

        e.stopPropagation(); //prevent bubbling (new-school)
        return false; //prevent bubbling (old-school)
      }
    });
  });
})();
  • 1
    Bug Report: Press Ctrl L when editing a comment. Input a URL and press Enter (instead of clicking OK in the input dialog). Comment gets submitted immediately (after linking the selected text). – ADTC Jan 27 '14 at 10:50
  • Also, in Firefox, pressing Ctrl-L shows the JS input dialog but the cursor is in the address bar. I have to click in the JS input box before pasting the URL. In Chrome, the JS dialog (which looks a lot nicer) already had focus so I could paste immediately. I guess this is a browser issue you can't fix on the add-on, but if you can, that will be great. – ADTC Jun 16 '14 at 6:58
  • I can't get this to work right now on Chrome for OS X. – Revetahw Oct 16 '16 at 14:57
  • 1
    I have published a more refined and improved userscript that does the same and much more: Comment keyboard shortcuts – Gaurang Tandon Jun 12 '18 at 10:36
5

Excellent script, much needed. I adjusted the following to make it work:

  • changed live by $(document).on( 'keydown', 'textarea[name=comment]', function(e) {})

  • added metakey so it works on Macs (e.ctrlKey||e.metaKey)

And other improvements:

  • only runs when viewing a question or in the Review/Task pages.

  • changed @include by @match using a format that catches both main and meta sites *://*.stackapps.com/questions*

Here's the modified script.

  • thanks i had noticed this stopped working but never got around to investigating why. jquery deprecation of .live() makes sense! – Kip Oct 6 '14 at 1:12
  • Please, feel free to incorporate whatever you want into the question's code. Also, pointing to a raw Gist/Github URL works ok. Cheers! – brasofilo Oct 6 '14 at 1:50
  • The script in OP didn't work for me. But this correction has no "install" link. How do I install it? – Revetahw Oct 16 '16 at 15:02
  • 1
    @Revetahw: Press "raw" button on the page to access code and your userscript manager should start installation. – user598527 Oct 21 '17 at 9:43
  • @user598527 Alright, thank you :) – Revetahw Oct 21 '17 at 9:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .