summaryrefslogtreecommitdiff
path: root/support/jed/jlm/latex_comm.sl
blob: 77be207698faa0c1b1b44da7e3a1bd604097fc35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
% File: latex_comm.sl                            -*- mode: SLang -*-
%
% Copyright (c)
%       2006--2007  Jörg Sommer <joerg@alea.gnuu.de>
%       $Id: latex_comm.sl 199 2007-08-23 23:28:52Z joerg $
%
%       -*- This file is part of Jörg's LaTeX Mode (JLM) -*-
%
% Description:   The dvi viewer Xdvi can communicate with the editor to
%                move the cursor to the possition of the file that is
%                related to the paragraph currently shown.
%
%                This file implements the communication helper for xdvi.
%
% License: This program is free software; you can redistribute it and/or
%	   modify it under the terms of the GNU General Public License as
%	   published by the Free Software Foundation; either version 2 of
%	   the License, or (at your option) any later version.
%
%          This program is distributed in the hope that it will be
%	   useful, but WITHOUT ANY WARRANTY; without even the implied
%	   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
%	   PURPOSE.  See the GNU General Public License for more details.

% Fixme: This is ugly, but
%   jed-script foo -> __argv = ["foo"]
%   jed --script foo -> __argv = ["jed", "--script", "foo"]

_for(0, length(__argv), 1)
{
    $0 = ();
    if ( is_substr(__argv[$0], "latex_comm.sl") )
    {
        ++$0;
        break;
    }
}

variable args = __argv[[$0:]];

variable STDIN_FILENO = fileno(stdin);
variable STDOUT_FILENO = fileno(stdout);

if ( andelse {length(args) == 1} {args[0] == "watch"} )
{
    variable fifo_name = "/tmp/jed.latex." + string(getpid());

    if (mkfifo(fifo_name, 0600) != 0)
      throw ApplicationError, "Could not create FIFO";

    () = write(STDOUT_FILENO, "communicator created: $fifo_name\n"$);

#ifexists SIGHUP
    variable quit = 0;
    eval("define sig_handler(sig) { quit = 1; }");
    signal(SIGHUP, __get_reference("sig_handler") );
    signal(SIGINT, __get_reference("sig_handler") );
    signal(SIGTERM, __get_reference("sig_handler") );

# iffalse
    % slang 2.0 has a bug---signal is set to restart system calls.
    % However, once a signal is caught, the signal will be set to
    % interrupt them, which is the correct behavior for the interpreter.
    % Force that here.
    () = kill(getpid(), SIGHUP);
    () = kill(getpid(), SIGINT);
    () = kill(getpid(), SIGTERM);
    quit = 0;
# endif
#endif

    try
    {
        forever
        {
            variable fifo = open(fifo_name, O_RDONLY);
            if (fifo == NULL)
              break;
#ifexists quit
            if (quit)
            {
                () = close(fifo);
                break;
            }
#endif
            try
            {
                variable line, last_line;
                while (read(fifo, &line, 128) > 0)
                {
                    () = write(STDOUT_FILENO, line);
                    last_line = line;
                }

                if (andelse {bstrlen(last_line) >= 5}
                     {last_line[[-5:-1]] == "quit\n"B})
                  break;
            }
            finally
              () = close(fifo);
        }
    }
    finally
      () = remove(fifo_name);
}
else
{
    if (length(args) < 2)
      throw NumArgsError, "missing arguments";

    variable stat = stat_file(args[0]);
    !if ( andelse {stat != NULL} {stat_is("fifo", stat.st_mode)} )
      throw InvalidParmError, "File "+args[0]+" do not exist or is not a FIFO";

    variable fifo = open(args[0], O_WRONLY);
    try
    {
        () = write(fifo, strjoin(args[[1:]], " ") + "\n");
    }
    finally
      () = close(fifo);
}