@@ -671,7 +671,7 @@ open_line(dir, flags, old_indent)
671
671
ptr = saved_line ;
672
672
# ifdef FEAT_COMMENTS
673
673
if (flags & OPENLINE_DO_COM )
674
- lead_len = get_leader_len (ptr , NULL , FALSE);
674
+ lead_len = get_leader_len (ptr , NULL , FALSE, TRUE );
675
675
else
676
676
lead_len = 0 ;
677
677
# endif
@@ -693,7 +693,7 @@ open_line(dir, flags, old_indent)
693
693
}
694
694
# ifdef FEAT_COMMENTS
695
695
if (flags & OPENLINE_DO_COM )
696
- lead_len = get_leader_len (ptr , NULL , FALSE);
696
+ lead_len = get_leader_len (ptr , NULL , FALSE, TRUE );
697
697
else
698
698
lead_len = 0 ;
699
699
if (lead_len > 0 )
@@ -836,7 +836,7 @@ open_line(dir, flags, old_indent)
836
836
*/
837
837
end_comment_pending = NUL ;
838
838
if (flags & OPENLINE_DO_COM )
839
- lead_len = get_leader_len (saved_line , & lead_flags , dir == BACKWARD );
839
+ lead_len = get_leader_len (saved_line , & lead_flags , dir == BACKWARD , TRUE );
840
840
else
841
841
lead_len = 0 ;
842
842
if (lead_len > 0 )
@@ -1548,14 +1548,18 @@ open_line(dir, flags, old_indent)
1548
1548
* When "flags" is not NULL, it is set to point to the flags of the recognized
1549
1549
* comment leader.
1550
1550
* "backward" must be true for the "O" command.
1551
+ * If "include_space" is set, include trailing whitespace while calculating the
1552
+ * length.
1551
1553
*/
1552
1554
int
1553
- get_leader_len (line , flags , backward )
1555
+ get_leader_len (line , flags , backward , include_space )
1554
1556
char_u * line ;
1555
1557
char_u * * flags ;
1556
1558
int backward ;
1559
+ int include_space ;
1557
1560
{
1558
1561
int i , j ;
1562
+ int result ;
1559
1563
int got_com = FALSE;
1560
1564
int found_one ;
1561
1565
char_u part_buf [COM_MAX_LEN ]; /* buffer for one option part */
@@ -1565,7 +1569,7 @@ get_leader_len(line, flags, backward)
1565
1569
char_u * prev_list ;
1566
1570
char_u * saved_flags = NULL ;
1567
1571
1568
- i = 0 ;
1572
+ result = i = 0 ;
1569
1573
while (vim_iswhite (line [i ])) /* leading white space is ignored */
1570
1574
++ i ;
1571
1575
@@ -1668,17 +1672,167 @@ get_leader_len(line, flags, backward)
1668
1672
if (!found_one )
1669
1673
break ;
1670
1674
1675
+ result = i ;
1676
+
1671
1677
/* Include any trailing white space. */
1672
1678
while (vim_iswhite (line [i ]))
1673
1679
++ i ;
1674
1680
1681
+ if (include_space )
1682
+ result = i ;
1683
+
1675
1684
/* If this comment doesn't nest, stop here. */
1676
1685
got_com = TRUE;
1677
1686
if (vim_strchr (part_buf , COM_NEST ) == NULL )
1678
1687
break ;
1679
1688
}
1689
+ return result ;
1690
+ }
1691
+
1692
+ /*
1693
+ * Return the offset at which the last comment in line starts. If there is no
1694
+ * comment in the whole line, -1 is returned.
1695
+ *
1696
+ * When "flags" is not null, it is set to point to the flags describing the
1697
+ * recognized comment leader.
1698
+ */
1699
+ int
1700
+ get_last_leader_offset (line , flags )
1701
+ char_u * line ;
1702
+ char_u * * flags ;
1703
+ {
1704
+ int result = -1 ;
1705
+ int i , j ;
1706
+ int lower_check_bound = 0 ;
1707
+ char_u * string ;
1708
+ char_u * com_leader ;
1709
+ char_u * com_flags ;
1710
+ char_u * list ;
1711
+ int found_one ;
1712
+ char_u part_buf [COM_MAX_LEN ]; /* buffer for one option part */
1713
+
1714
+ /*
1715
+ * Repeat to match several nested comment strings.
1716
+ */
1717
+ i = (int )STRLEN (line );
1718
+ while (-- i >= lower_check_bound )
1719
+ {
1720
+ /*
1721
+ * scan through the 'comments' option for a match
1722
+ */
1723
+ found_one = FALSE;
1724
+ for (list = curbuf -> b_p_com ; * list ; )
1725
+ {
1726
+ char_u * flags_save = list ;
1727
+
1728
+ /*
1729
+ * Get one option part into part_buf[]. Advance list to next one.
1730
+ * put string at start of string.
1731
+ */
1732
+ (void )copy_option_part (& list , part_buf , COM_MAX_LEN , "," );
1733
+ string = vim_strchr (part_buf , ':' );
1734
+ if (string == NULL ) /* If everything is fine, this cannot actually
1735
+ * happen. */
1736
+ {
1737
+ continue ;
1738
+ }
1739
+ * string ++ = NUL ; /* Isolate flags from string. */
1740
+ com_leader = string ;
1680
1741
1681
- return (got_com ? i : 0 );
1742
+ /*
1743
+ * Line contents and string must match.
1744
+ * When string starts with white space, must have some white space
1745
+ * (but the amount does not need to match, there might be a mix of
1746
+ * TABs and spaces).
1747
+ */
1748
+ if (vim_iswhite (string [0 ]))
1749
+ {
1750
+ if (i == 0 || !vim_iswhite (line [i - 1 ]))
1751
+ continue ;
1752
+ while (vim_iswhite (string [0 ]))
1753
+ ++ string ;
1754
+ }
1755
+ for (j = 0 ; string [j ] != NUL && string [j ] == line [i + j ]; ++ j )
1756
+ /* do nothing */ ;
1757
+ if (string [j ] != NUL )
1758
+ continue ;
1759
+
1760
+ /*
1761
+ * When 'b' flag used, there must be white space or an
1762
+ * end-of-line after the string in the line.
1763
+ */
1764
+ if (vim_strchr (part_buf , COM_BLANK ) != NULL
1765
+ && !vim_iswhite (line [i + j ]) && line [i + j ] != NUL )
1766
+ {
1767
+ continue ;
1768
+ }
1769
+
1770
+ /*
1771
+ * We have found a match, stop searching.
1772
+ */
1773
+ found_one = TRUE;
1774
+
1775
+ if (flags )
1776
+ * flags = flags_save ;
1777
+ com_flags = flags_save ;
1778
+
1779
+ break ;
1780
+ }
1781
+
1782
+ if (found_one )
1783
+ {
1784
+ char_u part_buf2 [COM_MAX_LEN ]; /* buffer for one option part */
1785
+ int len1 , len2 , off ;
1786
+
1787
+ result = i ;
1788
+ /*
1789
+ * If this comment nests, continue searching.
1790
+ */
1791
+ if (vim_strchr (part_buf , COM_NEST ) != NULL )
1792
+ continue ;
1793
+
1794
+ lower_check_bound = i ;
1795
+
1796
+ /* Let's verify whether the comment leader found is a substring
1797
+ * of other comment leaders. If it is, let's adjust the
1798
+ * lower_check_bound so that we make sure that we have determined
1799
+ * the comment leader correctly.
1800
+ */
1801
+
1802
+ while (vim_iswhite (* com_leader ))
1803
+ ++ com_leader ;
1804
+ len1 = (int )STRLEN (com_leader );
1805
+
1806
+ for (list = curbuf -> b_p_com ; * list ; )
1807
+ {
1808
+ char_u * flags_save = list ;
1809
+
1810
+ (void )copy_option_part (& list , part_buf2 , COM_MAX_LEN , "," );
1811
+ if (flags_save == com_flags )
1812
+ continue ;
1813
+ string = vim_strchr (part_buf2 , ':' );
1814
+ ++ string ;
1815
+ while (vim_iswhite (* string ))
1816
+ ++ string ;
1817
+ len2 = (int )STRLEN (string );
1818
+ if (len2 == 0 )
1819
+ continue ;
1820
+
1821
+ /* Now we have to verify whether string ends with a substring
1822
+ * beginning the com_leader. */
1823
+ for (off = (len2 > i ? i : len2 ); off > 0 && off + len1 > len2 ;)
1824
+ {
1825
+ -- off ;
1826
+ if (!STRNCMP (string + off , com_leader , len2 - off ))
1827
+ {
1828
+ if (i - off < lower_check_bound )
1829
+ lower_check_bound = i - off ;
1830
+ }
1831
+ }
1832
+ }
1833
+ }
1834
+ }
1835
+ return result ;
1682
1836
}
1683
1837
#endif
1684
1838
0 commit comments