ActiveBlog

Revenge of the auto-wrap (type type type DING!)
by Troy Topnik

Troy Topnik, November 6, 2008

"I do not think anyone wants Komodo to add breaks -- that is not what
word-wrap does."
-- Cory Trese on

komodo-discuss
March 2002

As someone who uses Komodo mostly to edit text and HTML, my
perspective on how an editor should behave differs somewhat from users
who spend all day hacking in dynamic languages. One such behavior I find
it hard to live without is "auto-wrap", the automatic insertion of line
breaks at a pre-defined column.

Now, I didn't know it when I filed this bug,
but Komodo did at one time have an
auto-wrap feature
.

Once Scintilla grew the ability to wrap lines without line breaks,
word wrap was added to Komodo and auto-wrap relegated to handling
comment wrapping only. This has always been a frustration for me, but I
learned to work around it by hitting 'Ctrl'+'Q' to reflow paragraphs as
I typed.

However, when I started using Komodo
as an email editor
, reflowing each line whenever I hit the line edge
started seeming a bit absurd. It suddenly occurred to me that what I was
doing was equivalent to using a manual typewriter with a bell that rang
when you got close to the margin stop.

type type type type type type DING (ka-

chunk) type type type...

Knowing just enough about Komodo macros to get myself into
trouble, I managed to get Todd interested enough
about my cryptic questions about event listeners to come help me with the
tricky bits. Let's walk through what we came up with - tutorial
style.

The first thing we'll need is an event
listener
to keep an eye on our cursor position in the editor. There
are more elegant (and efficient) ways to do this in Komodo, but this is
just a quick and dirty macro.

ko.views.manager.topView.addEventListener("keypress", autoReflow, true);

This watches the editor pane (all tabs) for keypress events and runs
"autoReflow" each time (I didn't claim this was going to be efficient
code). Let's create that now:

autoReflow = function (event) {
  var scimoz = ko.views.manager.currentView.scimoz;
  if (scimoz.getColumn(scimoz.currentPos) > 72) {
    alert("DING!");
  }
}

The first line defines our "autoReflow" function under the global window namespace. The next gives us a convenient shortcut for the scimoz
object which we then use to get the current position of the cursor. If
it's greater than 72, we pop up an alert and take a giant leap backwards
in usability. Let's do something a little more helpful.

Looking through Komodo's command ID
list
I see that "Reflow paragraph(s)" is accessed via
"cmd_editReflow". To run that in a macro we use:

  ko.commands.doCommand("cmd_editReflow");

Putting it all together we get:

autoReflow = function (event) {
  var scimoz = ko.views.manager.currentView.scimoz;
  if (scimoz.getColumn(scimoz.currentPos) > 72) {
    ko.commands.doCommand("cmd_editReflow");
  }
}
ko.views.manager.topView.addEventListener("keypress", autoReflow, true);

Now we can type away to our hearts content and Komodo will
automatically wrap lines for us when we get to column 72. This is great
until we start editing code. We need a way to turn this off, which we
can do with another macro that cancels the event handler:

ko.views.manager.topView.removeEventListener("keypress", autoReflow, true);

Not the fanciest way to do it, but I've put these two macros in a custom
toolbar
so that I can turn wrapping on and off when I need to.

I would be soundly spanked by the Komodo developers if I did not add
one more "best practices" element to this macro. The autoReflow function
is currently residing in the global namespace. To guard against the
possibility that it might conflict with a function in another macro or
extension, we should put it in our own
namespace
:

if (typeof (mymacros) == "undefined") {
  mymacros = {};
}
mymacros.autoReflow = function (event) {
  var scimoz = ko.views.manager.currentView.scimoz;
  if (scimoz.getColumn(scimoz.currentPos) > 72) {
    ko.commands.doCommand("cmd_editReflow");
  }
}
ko.views.manager.topView.addEventListener("keypress", mymacros.autoReflow, true);

... and of course the same thing in the "stop" macro:

if (typeof (mymacros) == "undefined") {
  mymacros = {};
}
ko.views.manager.topView.removeEventListener("keypress", mymacros.autoReflow, true);

If creating this namespace in all your macros looks like too much
effort, you can create it in a separate macro that's triggered
when you start Komodo
. That way, the "mymacros" namespace is
available in all your macros.

"I do not think anyone wants Komodo to add breaks -- that is not what
word-wrap does."
-- Cory Trese on
href="http://aspn.activestate.com/ASPN/Mail/Message/komodo-discuss/1092759">
komodo-discuss March 2002

As someone who uses Komodo mostly to edit text and HTML, my
perspective on how an editor should behave differs somewhat from users
who spend all day hacking in dynamic languages. One such behavior I find
it hard to live without is "auto-wrap", the automatic insertion of line
breaks at a pre-defined column.

Now, I didn't know it when I filed href="http://bugs.activestate.com/show_bug.cgi?id=74264">this bug,
but Komodo did at one time have an href="http://aspn.activestate.com/ASPN/Mail/Message/komodo-discuss/1319890">
auto-wrap feature.

Once Scintilla grew the ability to wrap lines without line breaks,
word wrap was added to Komodo and auto-wrap relegated to handling
comment wrapping only. This has always been a frustration for me, but I
learned to work around it by hitting 'Ctrl'+'Q' to reflow paragraphs as
I typed.

However, when I started href="http://www.openkomodo.com/blogs/troyt/its-all-komodo">using Komodo
as an email editor, reflowing each line whenever I hit the line edge
started seeming a bit absurd. It suddenly occurred to me that what I was
doing was equivalent to using a manual typewriter with a bell that rang
when you got close to the margin stop.

type type type type type type DING (ka-

chunk) type type type...

Knowing just enough about Komodo macros to get myself into
trouble, I managed to get href="http://www.openkomodo.com/blogs/toddw">Todd interested enough
about my cryptic questions about event listeners to come help me with the
tricky bits. Let's walk through what we came up with - tutorial
style.

The first thing we'll need is an href="https://developer.mozilla.org/en/DOM/element.addEventListener">event
listener to keep an eye on our cursor position in the editor. There
are more elegant (and efficient) ways to do this in Komodo, but this is
just a quick and dirty macro.

ko.views.manager.topView.addEventListener("keypress", autoReflow, true);

This watches the editor pane (all tabs) for keypress events and runs
"autoReflow" each time (I didn't claim this was going to be efficient
code). Let's create that now:

autoReflow = function (event) {
  var scimoz = ko.views.manager.currentView.scimoz;
  if (scimoz.getColumn(scimoz.currentPos) > 72) {
    alert("DING!");
  }
}

The first line defines our "autoReflow" function under the global window namespace. The next gives us a convenient shortcut for the href="http://docs.activestate.com/komodo/5.0/macroapi.html#macroapi_scimoz">scimoz
object which we then use to get the current position of the cursor. If
it's greater than 72, we pop up an alert and take a giant leap backwards
in usability. Let's do something a little more helpful.

Looking through Komodo's href="http://docs.activestate.com/komodo/5.0/commandid.html">command ID
list I see that "Reflow paragraph(s)" is accessed via
"cmd_editReflow". To run that in a macro we use:

  ko.commands.doCommand("cmd_editReflow");

Putting it all together we get:

autoReflow = function (event) {
  var scimoz = ko.views.manager.currentView.scimoz;
  if (scimoz.getColumn(scimoz.currentPos) > 72) {
    ko.commands.doCommand("cmd_editReflow");
  }
}
ko.views.manager.topView.addEventListener("keypress", autoReflow, true);

Now we can type away to our hearts content and Komodo will
automatically wrap lines for us when we get to column 72. This is great
until we start editing code. We need a way to turn this off, which we
can do with another macro that cancels the event handler:

ko.views.manager.topView.removeEventListener("keypress", autoReflow, true);

Not the fanciest way to do it, but I've put these two macros in a href="http://docs.activestate.com/komodo/5.0/custtbi.html">custom
toolbar so that I can turn wrapping on and off when I need to.

I would be soundly spanked by the Komodo developers if I did not add
one more "best practices" element to this macro. The autoReflow function
is currently residing in the global namespace. To guard against the
possibility that it might conflict with a function in another macro or
extension, we should put it in href="http://www.openkomodo.com/blogs/jeffg/namspaces-please">our own
namespace:

if (typeof (mymacros) == "undefined") {
  mymacros = {};
}
mymacros.autoReflow = function (event) {
  var scimoz = ko.views.manager.currentView.scimoz;
  if (scimoz.getColumn(scimoz.currentPos) > 72) {
    ko.commands.doCommand("cmd_editReflow");
  }
}
ko.views.manager.topView.addEventListener("keypress", mymacros.autoReflow, true);

... and of course the same thing in the "stop" macro:

if (typeof (mymacros) == "undefined") {
  mymacros = {};
}
ko.views.manager.topView.removeEventListener("keypress", mymacros.autoReflow, true);

If creating this namespace in all your macros looks like too much
effort, you can create it in a separate macro that's href="http://docs.activestate.com/komodo/5.0/macros.html#triggers_macros">triggered
when you start Komodo. That way, the "mymacros" namespace is
available in all your macros.

Subscribe to ActiveState Blogs by Email

Share this post:

About the Author: RSS

Troy Topnik is ActiveState's technical writer. After joining ActiveState in 2001 as a "Customer Relationship Representative" (AKA Tech Support), Troy went on to lead the PureMessage Enterprise Support team before moving on to a technical writing role in 2004. His talent for describing software for new users stems from his difficulty understanding things that developers find obvious. He has a Bachelor of Music from the University of Victoria.