rnkn / fountain-mode

Emacs major mode for screenwriting in Fountain plain-text markup
https://fountain-mode.org
GNU General Public License v3.0
399 stars 15 forks source link

Add emphasis markup functions #120

Closed zck closed 4 years ago

zck commented 4 years ago

These are simple functions to make it easier to make text bold and italic. I submitted this PR rather than open an issue because the functions were easy enough to write.

I bound them to C-c b and C-c i, because that made the most sense to me; C-c C-i is already taken.

Eventually, these should remove bold and italic, if called on text that already has these properties. But they're still quite useful now.

rnkn commented 4 years ago

Cool feature.

A couple of things to consider:

zck commented 4 years ago

I've made a few commits, so you can more easily see what's changed. I can squash them together if you'd rather them be as one commit at the end.

I've:

  1. Added fountain-underline-dwim.
  2. Changed the keybindings to begin with C-c C-f. I don't love it being an extra keypress, but I can't think of anything better either. I assume C-f is for "format"; and could expand to other formatting functions? There's a few somewhat related ones, but they feel somewhat different (fountain-upcase-line, fountain-upcase-line-and-newline).
  3. Used (region-beginning) and (region-end).

Account for when point is within or at the boundaries of a word. This probably where I'd go with another approach, e.g. first find insertion points, then insert chars.

If I'm understanding properly, you want this text (no active region; the | indicates point)

foun|tain

when called with fountain-italicize-dwim, to be marked up as:

*foun|tain*

Is this right?

Do you want this behavior for when there is a selected region, when there isn't, or both? I think it makes sense only when there isn't a selected region. If the user did select a region, I tend to think they have told us what they want.

rnkn commented 4 years ago

I'm concerned that you may have underestimated the complexity of this feature. With respect to how these commands should behave depending on location of point, you'd need to consider the user natural expectation when point is: within whitespace, at the beginning of a word, within the word, and at the end of a word. You'd need to reconsider each of these when that location is both within and not within the existing markup (e.g. within bold markup when calling fountain-insert-bold or fountain-toggle-bold or whatever).

This is important. I've not implemented such convenience features so far because getting this wrong interferes with a writer's creative flow.

I think there's still a bit of work to be done on this.

Just for the code, to compile cleanly, the function fountain--markup-dwim needs to be defined before first called. It's also probably better to define as a command itself than a private function, since the other commands are just wrapper/convenience commands, but rather than make wrapper functions, it would be more user-friendly to provide the markup argument interactively, e.g.

(interactive
   (list (read-char-choice "Insert markup [Bold, Italic, Underline]: "
                           '(?b ?i ?u))))

The keys aren't a big deal. You can shadow it with M-o.

zck commented 4 years ago

I think the way you want this to work is very different from how I do, and I'm not especially interested in developing use patterns I dislike (prompting the user takes them out of flow).

I'm also, honestly, a little frustrated that feedback on the design of the feature is coming only in the second round of feedback. The time I've spent making changes from the first round is wasted, because the design changed so much. Also, it seems like you expect me to intuitively know your vision for what "the user" wants. This is difficult, especially when I'm a user, and these functions already are a great help to me.

What is the actual set of features you want here? Given the gulf between what I seem to find helpful and what you want, I don't think I can intuit what you mean by the "user's natural expectation". For example, I've never worked with software that, when you say "make it bold" with no text selected, selects the word the user is in and emboldens that. Google Docs, for example, does not work that way. I would find that surprising.

rnkn commented 4 years ago

Sorry to make you feel your time has not been valued.

It's probably better if you open an issue requesting this feature, because the code as it stands is not at a level I would happily merge, and I don't want to waste more of your time trying to get it there.

What I most appreciate is that you've taken the time to demonstrate that this is an important feature, and I would appreciate any further insights into what you'd see as good/bad use patterns, e.g. if you have markdown-mode I'd certainly be interested in hearing your critique on the way it deals with applying/toggling emphasis markup.

rnkn commented 4 years ago

In master branch, enabling electric-pair-local-mode in fountain-mode-hook will now give you emphasis insertion functionality with just the * and _ keys: when region is active, it will surround with pair, when not it will insert pair with point inside.

zck commented 4 years ago

Oh, very interesting! Thanks for the feature. Did you still want an issue opened? I hadn't got time to write anything up yet, but I still could if you think it's worthwhile.

rnkn commented 4 years ago

Have a play with electric-pair-local-mode and see what you run into. It works well for italics and underline and is highly configurable to work the way you find most comfortable. The only issue is skipping bold delimiters, because it expects single pairs, not pairs of pairs, i.e. I'm still looking at how to get * to skip when at **fountain*|*.

Above appears solved in latest commit.