Notepad2e icon indicating copy to clipboard operation
Notepad2e copied to clipboard

Treat quotes as braces

Open ProgerXP opened this issue 5 years ago • 10 comments
trafficstars

~~According to changes in #283 it must be easy to~~ Treat quotes like brackets (for commands like Ctrl+B, highlighting and others) - make a new INI setting that switches between only braces (Notepad2, Unwrap Brackets; default) and braces + quotes (all symbols handled by Unwrap Quotes).

if (StrChrA("()[]{}<>", c))
if (StrChrA("()[]{}<>'\"`", c))

ProgerXP avatar Mar 08 '20 12:03 ProgerXP

Specified change is insufficient since this feature reuses Scintilla's SCI_BRACEMATCH command:

The brace characters handled are '(', ')', '[', ']', '{', '}', '<', and '>'

Implementation of specified INI setting will require some time.

cshnik avatar Mar 12 '20 18:03 cshnik

Done. Please consider the following:

  1. Scintilla code was patched to provide simple and clear solution (SCI_BRACEMATCH message handler).
  2. Braces have different opening and closing characters ()[]<>{} which makes it possible to automatically select the proper search direction (forward/backward) when running Find Matching Brace command.
  3. Quote characters have no difference for begin/end positions.
  4. Current implementation define these cases when determining search direction for quotes:
  • return -1 if there are no forward/backward occurrences
  • use forward direction if there is no backward quote character
  • use backward direction if there is no forward quote character
  • use nearest position (between backward/forward occurrence) in case of no breaking character found between current and nearest positions (\r, \n, = these chars are treated as incorrect for quoting), alternative (i.e farest) position is used otherwise.

cshnik avatar Nov 17 '20 18:11 cshnik

TreatQuotesAsBraces INI option added: 0 - disabled (by default), 1 - enabled. Affects the commands: Find Matching Brace (Ctrl+B) Select To Matching Brace (Ctrl+Shift+B)

cshnik avatar Nov 17 '20 19:11 cshnik

typedef enum
{
  TQB_DISABLED = 0,
  TQB_ENABLED = 0,
} ETreatQuotesAsBraces;

Isn't it TQB_ENABLED = 1?

ProgerXP avatar Jan 13 '21 15:01 ProgerXP

Fixed: removed useless code.

cshnik avatar Jan 15 '21 16:01 cshnik

How complex is it to extend this behaviour towards View > Visual Brace Matching?

ProgerXP avatar Jan 26 '21 15:01 ProgerXP

How complex is it to extend this behaviour towards View > Visual Brace Matching?

Done.

cshnik avatar Jan 27 '21 18:01 cshnik

Current implementation define these cases when determining search direction for quotes:

After using it I found that the algorithm is too complex to be reliable for the user (i.e. user cannot easily predict its behaviour). The algorithm used for Unwrap Quotes At Cursor is much better (it was implemented in #39) - it simply seeks leftwards, then rightwards. Let's use the same algorithm for Unwrap Quotes, Unwrap Brackets and Find/Select Matching Brace (this issue).

ProgerXP avatar Oct 11 '21 10:10 ProgerXP

it simply seeks leftwards, then rightwards

Please consider the following:

  1. Basic operation is Find matching 'quote' (Ctrl+B).
  2. There are 2 modes for matching-operation: move cursor inside or outside brackets/quotes (depends on initial cursor position).
  3. Since quotes has no direction (no difference between leading/trailing quotes) there is no way to detect which direction should be used when moving cursor to matching one. This means on every call we will always move cursor left to the previous quote when working in outside quotes mode.
  4. Which of the positions (left/right) should be used in this algorithm when moving between matching quotes in both inside/outside modes?

test "string" a |"test" string

cshnik avatar Aug 09 '22 21:08 cshnik

Found a related bug. Document:

' ' '

Press Home, then End - all 3 quotes will be highlighted (until you cause repaint by any means).


Current implementation is problematic because it uses some questionably heuristics:

'   '|   '

Depending on the number of spaces around the apostrophes, it will either match ^' ' or ' '$. This is simple to implement but it is not intuitive and cannot reliably predict the actual quotes used in the document (i.e. space between two separate nearby strings is seen as a string itself: 'a'.|'b').

Again, #39 is predictable as described in https://github.com/ProgerXP/Notepad2e/issues/39#issuecomment-66287371. In my example, it will always match ' '$ because it first seeks to the left, finds the middle ', then seeks to the right.

However, you are correct that we need to distinguish inner and outer quotes. It seems we have to implement a better algorithm that scans current line (up to a maximum limit of 1000 symbols), counting quotes and backslashes. If line start wasn't found on the left within the limit, fall back to #39's algorithm (meaning quotes are always assumed to be outside).

#39 itself should be reworked to use the new algorithm so that results of calling Ctrl+Shift+4 and Ctrl+B are the same.

ProgerXP avatar Aug 10 '22 11:08 ProgerXP

Recent changes mostly addressed the issue. Additionally, we disabled highlighting for escaped quotes (now rendered as plain text, not as unmatched brace).

The only remaining (and unmentioned) case is nested quotes: "I'm" "I'm" - both ' are currently seen as a valid string. This warrants some thinking.

ProgerXP avatar Nov 09 '22 13:11 ProgerXP

Fixed in the master branch.

cshnik avatar Nov 10 '22 06:11 cshnik