Search code examples
pythonsublimetext3sublime-text-plugin

How to get the (automatic) wrapping column ↔ the width of the view in columns?


I would like to get the column at which the text would be wrapped in the "Automatic" word wrap width. In other words, what I need is the width of the text window in columns. I've tried the following code, however window_to_text method seems to return 0 regardless of its input…

max_size = ex_view.viewport_extent()
max_size = (max_size[0] - 5, 1)
print(str(ex_view.rowcol(ex_view.window_to_text(max_size))[0]))

Solution

  • The main thing biting you here is that the API method view.window_to_text() tells you, based on a particular window position, what text point that refers to, but a text point isn't what you think it is (or rather, isn't reckoned the way you think it is).

    The content of a buffer is revealed to the API as one long string whose length represents the number of characters being displayed, and a point is an offset into that string. So for example if the buffer contains the text "Hello", valid text points range from 0 through 4 inclusive.

    As the view.window_to_text() has to return a text point in the range of 0-4 (in this example), what it does is determine what the closest character to that position is. For example a position to the right of the rightmost character in a line returns a point that represents the last character in the line, and a position that's below all of the content in the file returns the last character in the file.

    In order to use this method to determine the width of the buffer (or the height, for that matter) you would need to test by adding enough text to the buffer to ensure that there's text under the position you provide, which is probably not what you want.

    To calculate how large the viewport for a view is in characters in the general sense, you need to use view.em_width() and view.line_height(), which tell you the width and height of a character in dip respectively. From that you can easily calculate exactly how many columns and lines are currently potentially visible:

    >>> view.em_width()
    10.0
    >>> view.line_height()
    22.0
    >>> view.viewport_extent()
    (1215.0, 775.0)
    >>> 1215 // 10
    121
    >>> 775 // 22
    35