// // // The Nimrod Compiler // (c) Copyright 2009 Andreas Rumpf // // See the file "copying.txt", included in this // distribution, for details about the copyright. // unit rnimsyn; // This module implements the renderer of the standard Nimrod representation. {$include config.inc} interface uses nsystem, charsets, scanner, options, idents, strutils, ast, msgs, lists; type TRenderFlag = (renderNone, renderNoBody, renderNoComments, renderDocComments, renderNoPragmas, renderIds); TRenderFlags = set of TRenderFlag; TRenderTok = record kind: TTokType; len: int16; end; TRenderTokSeq = array of TRenderTok; TSrcGen = record indent: int; lineLen: int; pos: int; // current position for iteration over the buffer idx: int; // current token index for iteration over the buffer tokens: TRenderTokSeq; buf: string; pendingNL: int; // negative if not active; else contains the // indentation value comStack: array of PNode; // comment stack flags: TRenderFlags; end; procedure renderModule(n: PNode; const filename: string; renderFlags: TRenderFlags = {@set}[]); function renderTree(n: PNode; renderFlags: TRenderFlags = {@set}[]): string; procedure initTokRender(var r: TSrcGen; n: PNode; renderFlags: TRenderFlags = {@set}[]); procedure getNextTok(var r: TSrcGen; var kind: TTokType; var literal: string); implementation // We render the source code in a two phases: The first // determines how long the subtree will likely be, the second // phase appends to a buffer that will be the output. const IndentWidth = 2; longIndentWid = 4; MaxLineLen = 80; LineCommentColumn = 30; procedure InitSrcGen(out g: TSrcGen; renderFlags: TRenderFlags); begin {@ignore} fillChar(g, sizeof(g), 0); g.comStack := nil; g.tokens := nil; {@emit g.comStack := @[];} {@emit g.tokens := @[];} g.indent := 0; g.lineLen := 0; g.pos := 0; g.idx := 0; g.buf := ''; g.flags := renderFlags; g.pendingNL := -1; end; {@ignore} procedure add(var dest: string; const src: string); begin dest := dest +{&} src; end; {@emit} procedure addTok(var g: TSrcGen; kind: TTokType; const s: string); var len: int; begin len := length(g.tokens); setLength(g.tokens, len+1); g.tokens[len].kind := kind; g.tokens[len].len := int16(length(s)); add(g.buf, s); end; procedure addPendingNL(var g: TSrcGen); begin if g.pendingNL >= 0 then begin addTok(g, tkInd, NL+{&}repeatChar(g.pendingNL)); g.lineLen := g.pendingNL; g.pendingNL := -1; end end; procedure putNL(var g: TSrcGen; indent: int); overload; begin if g.pendingNL >= 0 then addPendingNL(g) else addTok(g, tkInd, NL); g.pendingNL := indent; g.lineLen := indent; end; procedure putNL(var g: TSrcGen); overload; begin putNL(g, g.indent); end; procedure optNL(var g: TSrcGen; indent: int); overload; begin g.pendingNL := indent; g.lineLen := indent; // BUGFIX end; procedure optNL(var g: TSrcGen); overload; begin optNL(g, g.indent) end; procedure indentNL(var g: TSrcGen); begin inc(g.indent, indentWidth); g.pendingNL := g.indent; g.lineLen := g.indent; end; procedure Dedent(var g: TSrcGen); begin dec(g.indent, indentWidth); assert(g.indent >= 0); if g.pendingNL > indentWidth then begin Dec(g.pendingNL, indentWidth); Dec(g.lineLen, indentWidth) end end; procedure put(var g: TSrcGen; const kind: TTokType; const s: string); begin addPendingNL(g); if length(s) > 0 then begin addTok(g, kind, s); inc(g.lineLen, length(s)); end end; procedure putLong(var g: TSrcGen; const kind: TTokType; const s: string; lineLen: int); // use this for tokens over multiple lines. begin addPendingNL(g); addTok(g, kind, s); g.lineLen := lineLen; end; // ----------------------- helpers -------------------------------------------- function toNimChar(c: Char): string; begin case c of #0: result := '\0'; #1..#31, #128..#255: result := '\x' + strutils.toHex(ord(c), 2); '''', '"', '\': result := '\' + c; else result := c + '' end; end; function makeNimString(const s: string): string; var i: int; begin result := '"' + ''; for i := strStart to length(s)+strStart-1 do add(result, toNimChar(s[i])); addChar(result, '"'); end; procedure putComment(var g: TSrcGen; s: string); var i, j, ind, comIndent: int; isCode: bool; com
dwm - dynamic window manager
============================
dwm is an extremely fast, small, and dynamic window manager for X.
Requirements
------------
In order to build dwm you need the Xlib header files.
Installation
------------
Edit config.mk to match your local setup (dwm is installed into
the /usr/local namespace by default).
Afterwards enter the following command to build and install dwm (if
necessary as root):
make clean install
Running dwm
-----------
Add the following line to your .xinitrc to start dwm using startx:
exec dwm
In order to connect dwm to a specific display, make sure that
the DISPLAY environment variable is set correctly, e.g.:
DISPLAY=foo.bar:1 exec dwm
(This will start dwm on display :1 of the host foo.bar.)
In order to display status info in the bar, you can do something
like this in your .xinitrc:
while true
do
echo `date` `uptime | sed 's/.*,//'`
sleep 1
done | dwm
Configuration
-------------
The configuration of dwm is done by creating a custom config.h
and (re)compiling the source code.