[comp.soft-sys.andrew] Lines And Columns

wjh+@ANDREW.CMU.EDU (Fred Hansen) (01/04/90)

Excerpts from andrew.hints: 17-Dec-89 Lines And Columns Jason Ari
Goldstein (421+0)

> How can I get ez or emacs to tell me what line and column number I am at?

The question is somewhat imprecise.  Is the origin of the count to be
the top of the screen or the top of the file?  How are wrapped lines to
be counted?

I will answer for ez here.

Finding the paragraph number with ESC-shift-N in ez finds the line
number with the origin at the beginning of the file and counting
everything between adjacent newline characters as a single line.  In
other words, the fact that a line may wrap on the screen is ignored.

The other functions are implemented by the Ness code listed below.  It
adds two keystroke combinations to ez:

    control-X control-L    This gives the position of the beginning of
    the selection on the screen.  

    escape-control-L   This gives the position of the beginning of the
    selection within its paragraph.  It ignores line wrapping.


To use these functions, you must have the version of Ness that is today
available on the X.V11R4 tape.  Put the Ness code below into a file, say
~/nesslib/loc.n, and then put into your ~/.atkinit file the two lines

load ness
call ness-load /afs/andrew/usr/<yourid>/nesslib/loc.n


The Ness code follows:
-- - - - - - - - - - - - - - - 
-- This ness file extends textview with two additional keystroke combinations: 



--  control-X control-L
--	When invoked, the message line shows the line and column number of
the beginning of the current selection, relative to the top of the
screen.  (If the selection begins offscreen, it is moved to be on
screen.)  The first line is numbered 1.  The column value is 1 if the
selection begins with the first character.

-- ESCape Control-L
--	When invoked, the message line displays the position of the start of
the current selection within its line,  where a line extends from one
newline character to the next.


-- This will only work with the /usr/andy software, which is scheduled
to move to campus sometime early in 1990.

--$Ness  1

-- loc_ScreenLine(m, object t)
--	determines what screen line the marker m starts on
--	m must be a marker onto the text for the textview object t
--	returns a negative value if m is not on the screen
--
	integer
function loc_ScreenLine(m, object t)
	integer line := 1
	marker s := currentselection(t)
	textview_cursor_to_bottom(t)
	textview_end_of_line(t)
	textview_forward_character(t)
	-- now currentselection(t) is just after end of screen
	if extent(currentselection(t), start(m)) /= "" then
		-- m is after bottom of screen
		setcurrentselection(t, s)
		return -2
	end if
	textview_cursor_to_top(t)
	-- cursor is at top of screen
	if extent(m, currentselection(t)) /= "" then
		-- m is before top of screen
		setcurrentselection(t, s)
		return -3
	end if
	textview_end_of_line(t)
	-- cursor is at end of top line of screen
	-- at each cycle of the loop, the cursor is at the end of a line
	while  extent(previous(m), currentselection(t)) = "" do 
		line := line + 1
		textview_next_line(t)
		textview_end_of_line(t)
	end while
	setcurrentselection(t, s)
	return line
end function


-- loc_ScreenColumn(m, object t)
--	determines what screen column the marker m starts before
--	m must be a marker onto the text for the textview object t
--	m must be on screen or else a loop will occur
--
	integer
function loc_ScreenColumn(m, object t)
	integer col := 1
	textview_beginning_of_line(t)
	textview_beginning_of_line(t)
	while extent(currentselection(t), start(m)) /= "" do
		col := col + 1
		textview_forward_character(t)
	end while
	setcurrentselection(t, m)
	return col
end function


-- loc_LinePosition(m)
--	determines the position of the beginning of marker m within its line
--	where a line is defined to extend from one newline character to the next
	integer
function loc_LinePosition(m)
	integer col := 1
	-- scan backward to beginning of line and increment 'col'
	while True do
		m := previous(m)
		if m = "\n" or m = "" then
			return col
		end if
		col := col + 1
	end while
end function



extend "view:textview" 
    on keys "\033\014"  -- ESC-control-l
	telluser("Col " ~
textimage(loc_LinePosition(start(currentselection(currentinset)))))
    end keys
    on keys ""  -- control-X control-L
	marker s := currentselection(currentinset)
	integer line := loc_ScreenLine(s, currentinset)
	if line < 0 then
		telluser("Selection did not begin on screen")
	else
		integer col := loc_ScreenColumn(s, currentinset);
		telluser("Line " ~ textimage(line) ~ "    Col " ~ textimage(col))
	end if
    end keys 
end extend