Take the 2-minute tour ×
Stack Apps is a question and answer site for apps, scripts, and development with the Stack Exchange API. It's 100% free, no registration required.

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

Install | View source

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!

Source

It seems that userscripts.org is dying. Here is the code:

// ==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)
      }
    });
  });
})();
share|improve this question
    
Awesome! Using it as we speak, and loving it! –  Cerberus Jun 2 '11 at 21:43
    
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 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 at 6:58
    
Update: UserScripts.org is down on port 80, but you can still access the site on port 8080. Here are the alternative links: Install | View source –  ADTC Jun 16 at 7:03

1 Answer 1

up vote 1 down vote accepted

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:

  • removed all with_jquery stuff, $ commands can run on the root (at least on Stack Exchange).

  • encapsulated all code inside an if( ( StackExchange.options.routeName.indexOf('Questions/Show') !== -1 ) ), so it only runs when viewing a question.

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

Here's the modified script.

share|improve this answer
    
thanks i had noticed this stopped working but never got around to investigating why. jquery deprecation of .live() makes sense! –  Kip Oct 6 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 at 1:50

You must log in to answer this question.

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