HEX
Server: Apache
System: Linux pdx1-shared-a1-38 6.6.104-grsec-jammy+ #3 SMP Tue Sep 16 00:28:11 UTC 2025 x86_64
User: mmickelson (3396398)
PHP: 8.1.31
Disabled: NONE
Upload Files
File: //usr/share/jed/lib/session.sl
% jed session save/restore
% 
% This file contains functions may be used to save and restore the
% partial state of a jed session.  By partial, it is meant that only
% the names of the files that are associated with buffers, the
% positions within those buffers, and some of the buffer flags are
% saved.  Other state information such as undo information,
% paste-buffers, etc are not saved.
% 
% To use this file, add the following near the end of your .jedrc file:
% 
%    require ("session");
%
% Then when jed starts up with no filenames specified on the command
% line, it will attempt to load a session file from the startup
% directory.  The files specified in the session file will be
% subsequently loaded.  If jed is started with one or more files given
% on the command-line, the previous session will not be loaded, nor
% will the current one be automatically saved.
% 
% By default, no session will be loaded or saved unless the startup
% directory contains a session file.  To initiate the saving of a
% session, you can either execute the save_session function, or create
% an empty session file in the startup directory.  If the save_session
% function is used, then the directory associated with the *scratch*
% buffer will be used for the session file.
% 
% The name of the session file may be set using
% the Session_Filename variable.  The default value is ".jedsession".
% 
% The Session_Exclude_Patterns variable is a list of regular
% expressions that are matched against a filename.  If a filename
% matches one of the patterns in the list, that filename will not be
% saved to the session file.  The function session_add_exclude_pattern
% may be used to add patterns to this variable.  Also, buffers that
% have the buffer-local variable save_session defined and set to 0
% will not be saved, as well as any buffer whose name begins with a
% space or '*' character.
%
% The format of the session file is very simple.  It consists of zero
% or more lines formatted as:
%
%    filename|linenumber|column|flags
%------------------------------------------------------------------------


%!%+
%\variable{Session_Filename}
%\synopsis{Name of the file where session information is saved}
%\usage{Session_Filename = ".jedsession";}
%\description
% The \svar{Session_Filename} function specifies the name of the file
% where session information is saved.  If the filename is a relative
% one, then it will be regarded as relative to the startup directory.
%\seealso{}
%!%-
custom_variable ("Session_Filename", ".jedsession");
custom_variable ("Session_Exclude_Patterns", NULL);

public define session_add_exclude_pattern (pat)
{
   if (Session_Exclude_Patterns == NULL)
     Session_Exclude_Patterns = {};
   list_append (Session_Exclude_Patterns, pat);
}

private variable This_Session_Filename = NULL;
private define expand_session_filename (file)
{
   if (path_is_absolute (file))
     return file;
   variable dir;
   (,dir,,) = getbuf_info ("*scratch*");
   return path_concat (dir, file);
}

private define exclude_filename (file)
{
   foreach (Session_Exclude_Patterns)
     {
	variable pat = ();
	if (string_match (file, pat, 1))
	  return 1;
     }
   return 0;
}

public define save_session ()
{
   variable session_file, do_error = 0;
   if (_NARGS == 0)
     {
	session_file = Session_Filename;
	do_error = 1;
     }
   else
     session_file = ();

   session_file = expand_session_filename (session_file);

   variable files = {}, lines = {}, columns = {}, flags = {};
   loop (buffer_list)
     {
	variable b = ();
	variable file = buffer_filename (b);
	if ((file == "") || (b[0] == ' ') || (b[0] == '*')
	    || exclude_filename (file))
	  continue;

	setbuf (b);
	ifnot (get_blocal_var ("save_session", 1))
	  continue;
	push_narrow ();
	widen_buffer();

	variable f; (,,,f) = getbuf_info ();
	list_append (flags, f);
	list_append (files, file);
	list_append (lines, what_line());
	list_append (columns, what_column());
	pop_narrow ();
     }

   variable fp = fopen (session_file, "w");
   if (fp == NULL)
     {
	variable msg = "Unable to save session to $file"$;
	if (do_error)
	  throw msg;
	message (msg);
	return;
     }

   () = chmod (file, 0600);
   _for (0, length(files)-1, 1)
     {
	variable i = ();
	() = fprintf (fp, "%s|%d|%d|%#lx\n", files[i], lines[i], columns[i], flags[i]);
     }
   () = fclose (fp);
}
add_completion ("save_session");

private define load_session ()
{
   variable do_error = 0, session_file;
   if (_NARGS == 0)
     session_file = Session_Filename;
   else
     {
	do_error = 1;
	session_file = ();
     }

   variable fp = fopen (session_file, "r");
   if (fp == NULL)
     {
	if (do_error)
	  throw OpenError, "Failed to open session file ${session_file}"$;
	return;
     }

   % Preserve the following flags:
   %   read-only (1<<3), overwrite (1<<4), crflag (1<<10)
   variable mask = (1<<3)|(1<<4)|(1<<10);
   variable str;
   while (-1 != fgets (&str, fp))
     {
	if (str[0] == '%')
	  continue;

	variable fields = strchop (str, '|', 0);
	variable file, line, col, flags;
	if ((length (fields) != 4)
	    || (1 != sscanf(fields[1], "%d", &line))
	    || (1 != sscanf(fields[2], "%d", &col))
	    || (1 != sscanf(fields[3], "0x%x", &flags)))
	  throw DataError, "session file appears corrupt";

	file = fields[0];

	if (NULL == stat_file (file))
	  continue;

	() = find_file (file);
	if (bobp())
	  {
	     variable f;
	     goto_line (line);
	     if (is_line_hidden ()
		 && (f = __get_reference ("fold_enter_fold"), f != NULL))
	       (@f)();

	     goto_column_best_try (col);
	  }

	_set_buffer_flag (flags&mask);
     }
   () = fclose (fp);
   This_Session_Filename = session_file;
}

private define startup_load_session_hook ()
{
   if (whatbuf () != "*scratch*")
     return;

   load_session ();
}
add_to_hook ("_jed_startup_hooks", &startup_load_session_hook);

private define exit_save_session_hook ()
{
   if (This_Session_Filename != NULL)
     save_session (This_Session_Filename);
   return 1;
}
add_to_hook ("_jed_exit_hooks", &exit_save_session_hook);