@@ -1767,8 +1767,8 @@ int guac_terminal_send_key(guac_terminal* term, int keysym, int pressed) {
1767
1767
1768
1768
/**
1769
1769
* Determines if the given character is part of a word.
1770
- * Match these chars :[0-9A-Za-z\$\%\&\ -\.\/\:\=\?\\ _~]
1771
- * This allows a path, URL, variable name or IP address to be treated as a word.
1770
+ * Match these chars :[0-9A-Za-z\$\-\.\/_~]
1771
+ * This allows a path, variable name or IP address to be treated as a word.
1772
1772
*
1773
1773
* @param ascii_char
1774
1774
* The character to check.
@@ -1782,17 +1782,42 @@ static bool guac_terminal_is_part_of_word(int ascii_char) {
1782
1782
(ascii_char >= 'A' && ascii_char <= 'Z' ) ||
1783
1783
(ascii_char >= 'a' && ascii_char <= 'z' ) ||
1784
1784
(ascii_char == '$' ) ||
1785
- (ascii_char == '%' ) ||
1786
- (ascii_char == '&' ) ||
1787
1785
(ascii_char == '-' ) ||
1788
1786
(ascii_char == '.' ) ||
1789
1787
(ascii_char == '/' ) ||
1788
+ (ascii_char == '_' ) ||
1789
+ (ascii_char == '~' ));
1790
+ }
1791
+
1792
+ /**
1793
+ * Determines if the given character is part of URI.
1794
+ * Match these chars :[%\&\+:;,=\?\!\*\\\(\)\[\]#] and word chars.
1795
+ *
1796
+ * @param ascii_char
1797
+ * The character to check.
1798
+ *
1799
+ * @return
1800
+ * true if match a "word" char,
1801
+ * false otherwise.
1802
+ */
1803
+ static bool guac_terminal_is_part_of_word_or_uri (int ascii_char ) {
1804
+ return (guac_terminal_is_part_of_word (ascii_char ) ||
1805
+ (ascii_char == '%' ) ||
1806
+ (ascii_char == '&' ) ||
1807
+ (ascii_char == '+' ) ||
1790
1808
(ascii_char == ':' ) ||
1809
+ (ascii_char == ';' ) ||
1810
+ (ascii_char == ',' ) ||
1791
1811
(ascii_char == '=' ) ||
1792
1812
(ascii_char == '?' ) ||
1813
+ (ascii_char == '!' ) ||
1814
+ (ascii_char == '*' ) ||
1793
1815
(ascii_char == '\\' ) ||
1794
- (ascii_char == '_' ) ||
1795
- (ascii_char == '~' ));
1816
+ (ascii_char == '(' ) ||
1817
+ (ascii_char == ')' ) ||
1818
+ (ascii_char == '[' ) ||
1819
+ (ascii_char == ']' ) ||
1820
+ (ascii_char == '#' ));
1796
1821
}
1797
1822
1798
1823
/**
@@ -1847,91 +1872,178 @@ static void guac_terminal_double_click(guac_terminal* terminal, int row, int col
1847
1872
bool (* is_part_of_word )(int ) = NULL ;
1848
1873
1849
1874
/* If selection is on a word, get its borders */
1850
- if (guac_terminal_is_part_of_word (cursor_char ))
1851
- is_part_of_word = guac_terminal_is_part_of_word ;
1875
+ if (guac_terminal_is_part_of_word_or_uri (cursor_char ))
1876
+ is_part_of_word = guac_terminal_is_part_of_word_or_uri ;
1852
1877
1853
1878
/* If selection is on a blank, get its borders */
1854
1879
else if (guac_terminal_is_blank (cursor_char ))
1855
1880
is_part_of_word = guac_terminal_is_blank ;
1856
1881
1857
1882
if (is_part_of_word != NULL ) {
1858
- /* Get word head*/
1883
+
1884
+ /* Event to exit loop */
1885
+ bool exit_loop = false;
1886
+
1859
1887
do {
1860
1888
1861
- /* Buffer row to get */
1862
- int current_row = word_row_head ;
1863
- int current_col = word_col_head ;
1889
+ /* Position of the word behind cursor.
1890
+ * Default = col/row required to select a char if not a word and not blank. */
1891
+ word_col_head = col ;
1892
+ word_col_tail = col ;
1893
+ word_row_head = row ;
1894
+ word_row_tail = row ;
1895
+
1896
+ /* Get word head*/
1897
+ do {
1898
+
1899
+ /* Buffer row to get */
1900
+ int current_row = word_row_head ;
1901
+ int current_col = word_col_head ;
1902
+
1903
+ /* Bound of screen reached: get previous row */
1904
+ if (word_col_head == 0 )
1905
+ current_row -- ;
1864
1906
1865
- /* Bound of screen reached: get previous row */
1866
- if (word_col_head == 0 )
1867
- current_row -- ;
1907
+ /* Get current buffer row */
1908
+ buffer_row = guac_terminal_buffer_get_row (terminal -> buffer , current_row , 0 );
1868
1909
1869
- /* Get current buffer row */
1870
- buffer_row = guac_terminal_buffer_get_row ( terminal -> buffer , current_row , 0 );
1910
+ /* If we are on the previous row */
1911
+ if ( current_row < word_row_head ) {
1871
1912
1872
- /* If we are on the previous row */
1873
- if (current_row < word_row_head ) {
1913
+ /* Line not wrapped: stop, it's the word boundary */
1914
+ if (!buffer_row -> wrapped_row )
1915
+ break ;
1916
+
1917
+ /* Go to last column of this row */
1918
+ current_col = buffer_row -> length ;
1919
+ }
1920
+
1921
+ /* Get char of the current row/column */
1922
+ flag = buffer_row -> characters [current_col - 1 ].value ;
1874
1923
1875
- /* Line not wrapped: stop, it's the word boundary */
1876
- if (!buffer_row -> wrapped_row )
1924
+ /* Word boundary reached, stop */
1925
+ if (!is_part_of_word ( flag ) )
1877
1926
break ;
1878
1927
1879
- /* Go to last column of this row */
1880
- current_col = buffer_row -> length ;
1881
- }
1928
+ /* Store new position on previous row */
1929
+ if (current_row < word_row_head ) {
1930
+ word_row_head = current_row ;
1931
+ word_col_head = current_col ;
1932
+ }
1882
1933
1883
- /* Get char of the current row/column */
1884
- flag = buffer_row -> characters [current_col - 1 ].value ;
1934
+ } while (word_col_head >= 0 && word_col_head -- );
1885
1935
1886
- /* Word boundary reached, stop */
1887
- if (!is_part_of_word (flag ))
1888
- break ;
1936
+ /* Get word tail */
1937
+ do {
1889
1938
1890
- /* Store new position on previous row */
1891
- if (current_row < word_row_head ) {
1892
- word_row_head = current_row ;
1893
- word_col_head = current_col ;
1894
- }
1939
+ /* Get current buffer row */
1940
+ buffer_row = guac_terminal_buffer_get_row (terminal -> buffer , word_row_tail , 0 );
1895
1941
1896
- } while (word_col_head >= 0 && word_col_head -- );
1942
+ /* Bound of screen reached and row is wrapped: get next row */
1943
+ if (word_col_tail == buffer_row -> length - 1 && buffer_row -> wrapped_row ) {
1897
1944
1898
- /* Get word tail */
1899
- do {
1945
+ /* Get next buffer row */
1946
+ guac_terminal_buffer_row * next_buffer_row =
1947
+ guac_terminal_buffer_get_row (terminal -> buffer , word_row_tail + 1 , 0 );
1900
1948
1901
- /* Get current buffer row */
1902
- buffer_row = guac_terminal_buffer_get_row ( terminal -> buffer , word_row_tail , 0 ) ;
1949
+ /* Get first char of the next row */
1950
+ flag = next_buffer_row -> characters [ 0 ]. value ;
1903
1951
1904
- /* Bound of screen reached and row is wrapped: get next row */
1905
- if (word_col_tail == buffer_row -> length - 1 && buffer_row -> wrapped_row ) {
1952
+ }
1906
1953
1907
- /* Get next buffer row */
1908
- guac_terminal_buffer_row * next_buffer_row =
1909
- guac_terminal_buffer_get_row ( terminal -> buffer , word_row_tail + 1 , 0 ) ;
1954
+ /* Otherwise, get char of next column on current row */
1955
+ else
1956
+ flag = buffer_row -> characters [ word_col_tail + 1 ]. value ;
1910
1957
1911
- /* Get first char of the next row */
1912
- flag = next_buffer_row -> characters [0 ].value ;
1958
+ /* Word boundary reached, stop */
1959
+ if (!is_part_of_word (flag ))
1960
+ break ;
1913
1961
1914
- }
1962
+ /* Store new position on next row */
1963
+ if (word_col_tail == buffer_row -> length - 1 && buffer_row -> wrapped_row ) {
1964
+ word_row_tail ++ ;
1965
+ word_col_tail = 0 ;
1966
+ }
1915
1967
1916
- /* Otherwise, get char of next column on current row */
1917
- else
1918
- flag = buffer_row -> characters [ word_col_tail + 1 ]. value ;
1968
+ /* Or go to next column of current row */
1969
+ else
1970
+ word_col_tail ++ ;
1919
1971
1920
- /* Word boundary reached, stop */
1921
- if (!is_part_of_word (flag ))
1972
+ } while (word_col_tail <= buffer_row -> length );
1973
+
1974
+ /* The following is only for URL scheme validation */
1975
+ if (is_part_of_word != guac_terminal_is_part_of_word_or_uri )
1922
1976
break ;
1923
1977
1924
- /* Store new position on next row */
1925
- if (word_col_tail == buffer_row -> length - 1 && buffer_row -> wrapped_row ) {
1926
- word_row_tail ++ ;
1927
- word_col_tail = 0 ;
1928
- }
1978
+ /* Temp vars to avoid overwrite word_row_head and word_col_head */
1979
+ int tmp_row = word_row_head ;
1980
+ int tmp_col = word_col_head ;
1929
1981
1930
- /* Or go to next column of current row */
1931
- else
1932
- word_col_tail ++ ;
1982
+ /* Check for the presence of a uri scheme like /^[a-z]+\:\/{2}/ */
1983
+ do {
1984
+
1985
+ /* Get first char of first row */
1986
+ buffer_row = guac_terminal_buffer_get_row (terminal -> buffer , tmp_row , 0 );
1987
+ cursor_char = buffer_row -> characters [tmp_col ].value ;
1988
+
1989
+ /* End of [a-z]+ part */
1990
+ if (cursor_char < 'a' || cursor_char > 'z' ) {
1991
+
1992
+ /* URI scheme delimiter :// foud */
1993
+ if (cursor_char == ':' &&
1994
+ buffer_row -> characters [tmp_col + 1 ].value == '/' &&
1995
+ buffer_row -> characters [tmp_col + 2 ].value == '/' ) {
1996
+
1997
+ /* Set exit event */
1998
+ exit_loop = true;
1999
+ break ;
2000
+ }
2001
+
2002
+ /* Not URI scheme */
2003
+ else
2004
+ break ;
2005
+ }
2006
+
2007
+ /* End of buffer row */
2008
+ else if (tmp_col == buffer_row -> length - 1 ) {
2009
+
2010
+ /* Confinue only if current buffer row is wrapped */
2011
+ if (buffer_row -> wrapped_row ) {
2012
+
2013
+ /* Stop if latest row */
2014
+ if (tmp_row == word_row_tail )
2015
+ break ;
2016
+
2017
+ /* Go to next row */
2018
+ tmp_row ++ ;
2019
+
2020
+ /* Go to first row (-1 for auto increment on next iteration) */
2021
+ tmp_col = 0 ;
2022
+
2023
+ /* Don't do further tests for this iteration */
2024
+ continue ;
2025
+
2026
+ }
2027
+
2028
+ /* End of selection without matching uri scheme */
2029
+ else
2030
+ break ;
2031
+
2032
+ }
2033
+
2034
+ /* End of selection without matching uri scheme */
2035
+ else if (tmp_row == word_row_tail && tmp_col == word_col_tail )
2036
+ break ;
2037
+
2038
+ tmp_col ++ ;
2039
+ //printf("tmp_row = %d | word_row_tail = %d | tmp_col = %d | word_col_tail = %d\n", tmp_row, word_row_tail, tmp_col, word_col_tail);
2040
+ } while (true);
2041
+
2042
+ /* Get word boundaries instead of URI */
2043
+ is_part_of_word = guac_terminal_is_part_of_word ;
1933
2044
1934
- } while (word_col_tail <= buffer_row -> length );
2045
+ printf ("!exit_loop = %d\n" , !exit_loop );
2046
+ } while (!exit_loop );
1935
2047
}
1936
2048
1937
2049
/* Select and add to clipboard the "word" */
0 commit comments