Loading NOTES.md +1 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ Switch between MAIL and BULLETIN modes? MAIL commands are documented * Remove all file related things. Which means no need for most (all?) /EDIT flags * Stop the seeded messages from being deleted by the expire batch command. * Run [godoc](http://localhost:6060/) and then review where the help text is lacking. * Implement each command. * Next: folder commands - MODIFY Loading batch/seed/2025-announce.txt +6 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,12 @@ remote folders are not supported. Commands and flags related to those haven't been implemented. In addition, it just uses a basic text editor, not an editor like EDT. Though I'm open to implementing one. Several commands accepted files or allowed messages to be put in files. All the file related functionality has been removed. The PRINT command has been implemented, but it depends on a terminal emulator implementing the passtrhru printing codes. Most do not. However the rest of BULLETIN works. There are message boards, you can add and read messages in them. Not all the commands work yet, but they are being added. Loading repl/command.go +22 −119 Original line number Diff line number Diff line Loading @@ -5,14 +5,13 @@ import "git.lyda.ie/kevin/bulletin/dclish" var commands = dclish.Commands{ "ADD": { Description: `Adds a message to the specified folder. A file can be specified which contains the message. Otherwise, BULLETIN will prompt for the text. BULLETIN will ask for an expiration date and a header to contain the topic of the message. Description: ` Adds a message to the specified folder. BULLETIN will invoke the editor for the text. BULLETIN will ask for an expiration date and a header to contain the topic of the message. Format: ADD [file-name]`, MaxArgs: 1, ADD`, Action: ActionAdd, Flags: dclish.Flags{ "/ALL": { Loading @@ -36,13 +35,6 @@ topic of the message. See also /ALL and /BELL.`, }, "/EDIT": { Description: `/[NO]EDIT Determines whether or not the editor is invoked to edit the message you are adding. /EDIT is the default.`, Default: "true", }, "/EXPIRATION": { Description: `/EXPIRATION=time Loading @@ -53,9 +45,8 @@ topic of the message. "/EXTRACT": { Description: ` Specifies that the text of the previously read message should be included at the beginning of the new message. The previous message must be in the same folder. This qualifier is valid only when used with /EDIT. The text is indented with > at the beginning of each line. This can be suppressed with /NOINDENT.`, must be in the same folder. The text is indented with > at the beginning of each line. This can be suppressed with /NOINDENT.`, }, "/FOLDER": { Description: `/FOLDER=(foldername,[...]) Loading Loading @@ -120,14 +111,6 @@ topic of the message. "BACK": { Description: `Displays the message preceding the current message.`, Action: ActionBack, Flags: dclish.Flags{ "/EDIT": { Description: `/EDIT Specifies that the editor is to be used to read the message. This is useful for scanning a long message.`, }, }, }, "CHANGE": { Description: `Replaces or modifies existing stored message. This is for changing part Loading @@ -135,28 +118,18 @@ or all of a message without causing users who have already seen the message to be notified of it a second time. You can select qualifiers so that either the message text, expiration date, or the header are to be changed. If no qualifier is added, the default is that all these parameters are to be changed. If the text of the message is to be changed, a file can be specified which contains the text. If the editor is used for changing the text, the old message text will be extracted. This can be suppressed by the qualifier /NEW. parameters are to be changed. The editor is used for changing the text and the old message text will be extracted. This can be suppressed by the qualifier /NEW. Format: CHANGE [file-name]`, MaxArgs: 1, CHANGE`, Action: ActionChange, Flags: dclish.Flags{ "/ALL": { Description: ` Makes the changes to all the messages in the folder. Only the expiration date and message headers can be changed if this qualifier is specified.`, }, "/EDIT": { Description: `/[NO]EDIT Determines whether or not the editor is invoked to edit the message you are replacing. The old message text is read into the editor unless a file-name or /NEW is specified. /EDIT is the default if you have added /EDIT to your BULLETIN command line.`, }, "/EXPIRATION": { Description: `/EXPIRATION[=time] Loading Loading @@ -360,12 +333,6 @@ of the message again, you can enter the CURRENT command. Format: CURRENT`, Action: ActionCurrent, Flags: dclish.Flags{ "/EDIT": { Description: ` Specifies that the editor is to be used to read the message. This is useful for scanning a long message.`, }, }, }, "DELETE": { Description: `Deletes the specified message. If no message is specified, the current Loading Loading @@ -511,37 +478,6 @@ that message.`, Description: `Exits the BULLETIN program.`, Action: ActionExit, }, "EXTRACT": { Description: `Synonym for FILE command.`, }, "FILE": { Description: `Copies the current message to the named file. The file-name parameter is required. If the file exists, the message is appended to the file, unless the /NEW qualifier is specified. Format: FILE filename [message_number][-message_number1],[...] A range of messages to be copied can optionally be specified, i.e FILE. 2-5 . The key words CURRENT and LAST can also be specified in the range in, place of an actual number, i.e. CURRENT-LAST, 1-CURRENT, etc.`, MinArgs: 1, MaxArgs: 2, Flags: dclish.Flags{ "/ALL": { Description: ` Copies all the messages in the current folder.`, }, "/FF": { Description: ` Specifies that a form feed is placed between messages in the file.`, }, "/NEW": { Description: ` Specifies that a new file is to be created. Otherwise, if the specified file exists, the file would be appended to that file.`, }, }, }, "FIRST": { Description: `Specifies that the first message in the folder is to be read.`, Action: ActionFirst, Loading Loading @@ -608,12 +544,6 @@ where one left off after one has read a message. Format: LAST`, Action: ActionLast, Flags: dclish.Flags{ "/EDIT": { Description: ` Specifies that the editor is to be used to read the message. This is useful for scanning a long message.`, }, }, }, "MAIL": { Description: `Invokes the VAX/VMS Personal Mail Utility (MAIL) to send the message Loading @@ -630,10 +560,6 @@ specified as xxx%"""address""".`, MinArgs: 1, MaxArgs: 10, Flags: dclish.Flags{ "/EDIT": { Description: ` Specifies that the editor is to be used to edit the message before mailing it.`, }, "/SUBJECT": { Description: `/SUBJECT=text Loading Loading @@ -745,12 +671,6 @@ place of an actual number, i.e. CURRENT-LAST, 1-CURRENT, etc.`, through the messages and you encounter a particularly long message that you would like to skip over.`, Action: ActionNext, Flags: dclish.Flags{ "/EDIT": { Description: ` Specifies that the editor is to be used to read the message. This is useful for scanning a long message.`, }, }, }, "PRINT": { Description: `Queues a copy of the message you are currently reading (or have just Loading Loading @@ -841,10 +761,6 @@ the help on the SEEN command.`, "/ALL": { Description: ` Specifies to read all messages. Used after /MARKED, /UNMARKED, /SEEN, or /UNSEEN had been specified.`, }, "/EDIT": { Description: ` Specifies that the editor is to be used to read the message. This is useful for scanning a long message.`, }, "/MARKED": { Description: ` Specifies to read only messages that have been marked (marked messages Loading Loading @@ -910,19 +826,14 @@ read message with "RE:" preceeding it. Format and qualifiers is exactly the same as the ADD command except for /NOINDENT and /EXTRACT. Format: REPLY [file-name]`, MaxArgs: 1, REPLY`, Action: ActionReply, Flags: dclish.Flags{ "/EDIT": { Description: ` Specifies that the editor is to be used for creating the reply message.`, }, "/EXTRACT": { Description: ` Specifies that the text of the message should be included in the reply message. This qualifier is valid only when used with /EDIT. The text of the message is indented with > at the beginning of each line. This can be suppressed with /NOINDENT.`, message. This is the default - suppress with /NOEXTRACT. The text of the message is indented with > at the beginning of each line. This can be suppressed with /NOINDENT.`, }, "/INDENT": { Description: ` See /EXTRACT for information on this qualifier. Loading @@ -937,28 +848,23 @@ the same as the ADD command except for /NOINDENT and /EXTRACT. message to the owner of the currently read message. Format: RESPOND [file-name] RESPOND If you wish to use another method for sending the mail, define BULL_MAILER to point to a command procedure. This procedure will then be executed in place of MAIL, and the parameters passed to it are the username and subject of the message.`, MaxArgs: 1, Flags: dclish.Flags{ "/CC": { Description: `/CC=user[s] Specifies additional users that should receive the reply.`, OptArg: true, }, "/EDIT": { Description: ` Specifies that the editor is to be used for creating the reply mail message.`, }, "/EXTRACT": { Description: ` Specifies that the text of the message should be included in the reply mail message. This qualifier is valid only when used with /EDIT. The text of the message is indented with > at the beginning of each line. This can be suppressed with /NOINDENT.`, mail message. This is the default - suppress with /NOEXTRACT. The text of the message is indented with > at the beginning of each line. This can be suppressed with /NOINDENT.`, }, "/LIST": { Description: ` Specifies that the reply should also be sent to the network mailing Loading Loading @@ -1012,9 +918,6 @@ search can be aborted by typing a CTRL-C.`, MinArgs: 1, MaxArgs: 1, Flags: dclish.Flags{ "/EDIT": { Description: ` Specifies that the editor is to be used for reading the message.`, }, "/FOLDER": { Description: `/FOLDER=(folder,[...]) Loading repl/messages.go +1 −3 Original line number Diff line number Diff line Loading @@ -151,7 +151,6 @@ func ActionAdd(cmd *dclish.Command) error { // ActionCurrent handles the `CURRENT` command. func ActionCurrent(_ *dclish.Command) error { // TODO: handle flags. msg, err := folders.ReadMessage(this.User.Login, this.Folder.Name, this.MsgID) if err != nil { return err Loading @@ -166,7 +165,6 @@ func ActionCurrent(_ *dclish.Command) error { // ActionBack handles the `BACK` command. func ActionBack(_ *dclish.Command) error { // TODO: handle flags. msgid := folders.PrevMsgid(this.User.Login, this.Folder.Name, this.MsgID) if msgid == 0 { fmt.Println("No previous messages") Loading Loading @@ -213,7 +211,6 @@ func ActionLast(_ *dclish.Command) error { // ActionNext handles the `NEXT` command. func ActionNext(_ *dclish.Command) error { // TODO: handle flags. msgid := folders.NextMsgid(this.User.Login, this.Folder.Name, this.MsgID) if msgid == 0 { fmt.Println("No next messages") Loading Loading @@ -257,6 +254,7 @@ func ActionPrint(cmd *dclish.Command) error { // ActionRead handles the `READ` command. func ActionRead(cmd *dclish.Command) error { // TODO: Implement the functionality of incrementing the message number *first* but not the first time the command is run. // TODO: handle flags. msgid := this.MsgID if len(cmd.Args) == 1 { Loading Loading
NOTES.md +1 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ Switch between MAIL and BULLETIN modes? MAIL commands are documented * Remove all file related things. Which means no need for most (all?) /EDIT flags * Stop the seeded messages from being deleted by the expire batch command. * Run [godoc](http://localhost:6060/) and then review where the help text is lacking. * Implement each command. * Next: folder commands - MODIFY Loading
batch/seed/2025-announce.txt +6 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,12 @@ remote folders are not supported. Commands and flags related to those haven't been implemented. In addition, it just uses a basic text editor, not an editor like EDT. Though I'm open to implementing one. Several commands accepted files or allowed messages to be put in files. All the file related functionality has been removed. The PRINT command has been implemented, but it depends on a terminal emulator implementing the passtrhru printing codes. Most do not. However the rest of BULLETIN works. There are message boards, you can add and read messages in them. Not all the commands work yet, but they are being added. Loading
repl/command.go +22 −119 Original line number Diff line number Diff line Loading @@ -5,14 +5,13 @@ import "git.lyda.ie/kevin/bulletin/dclish" var commands = dclish.Commands{ "ADD": { Description: `Adds a message to the specified folder. A file can be specified which contains the message. Otherwise, BULLETIN will prompt for the text. BULLETIN will ask for an expiration date and a header to contain the topic of the message. Description: ` Adds a message to the specified folder. BULLETIN will invoke the editor for the text. BULLETIN will ask for an expiration date and a header to contain the topic of the message. Format: ADD [file-name]`, MaxArgs: 1, ADD`, Action: ActionAdd, Flags: dclish.Flags{ "/ALL": { Loading @@ -36,13 +35,6 @@ topic of the message. See also /ALL and /BELL.`, }, "/EDIT": { Description: `/[NO]EDIT Determines whether or not the editor is invoked to edit the message you are adding. /EDIT is the default.`, Default: "true", }, "/EXPIRATION": { Description: `/EXPIRATION=time Loading @@ -53,9 +45,8 @@ topic of the message. "/EXTRACT": { Description: ` Specifies that the text of the previously read message should be included at the beginning of the new message. The previous message must be in the same folder. This qualifier is valid only when used with /EDIT. The text is indented with > at the beginning of each line. This can be suppressed with /NOINDENT.`, must be in the same folder. The text is indented with > at the beginning of each line. This can be suppressed with /NOINDENT.`, }, "/FOLDER": { Description: `/FOLDER=(foldername,[...]) Loading Loading @@ -120,14 +111,6 @@ topic of the message. "BACK": { Description: `Displays the message preceding the current message.`, Action: ActionBack, Flags: dclish.Flags{ "/EDIT": { Description: `/EDIT Specifies that the editor is to be used to read the message. This is useful for scanning a long message.`, }, }, }, "CHANGE": { Description: `Replaces or modifies existing stored message. This is for changing part Loading @@ -135,28 +118,18 @@ or all of a message without causing users who have already seen the message to be notified of it a second time. You can select qualifiers so that either the message text, expiration date, or the header are to be changed. If no qualifier is added, the default is that all these parameters are to be changed. If the text of the message is to be changed, a file can be specified which contains the text. If the editor is used for changing the text, the old message text will be extracted. This can be suppressed by the qualifier /NEW. parameters are to be changed. The editor is used for changing the text and the old message text will be extracted. This can be suppressed by the qualifier /NEW. Format: CHANGE [file-name]`, MaxArgs: 1, CHANGE`, Action: ActionChange, Flags: dclish.Flags{ "/ALL": { Description: ` Makes the changes to all the messages in the folder. Only the expiration date and message headers can be changed if this qualifier is specified.`, }, "/EDIT": { Description: `/[NO]EDIT Determines whether or not the editor is invoked to edit the message you are replacing. The old message text is read into the editor unless a file-name or /NEW is specified. /EDIT is the default if you have added /EDIT to your BULLETIN command line.`, }, "/EXPIRATION": { Description: `/EXPIRATION[=time] Loading Loading @@ -360,12 +333,6 @@ of the message again, you can enter the CURRENT command. Format: CURRENT`, Action: ActionCurrent, Flags: dclish.Flags{ "/EDIT": { Description: ` Specifies that the editor is to be used to read the message. This is useful for scanning a long message.`, }, }, }, "DELETE": { Description: `Deletes the specified message. If no message is specified, the current Loading Loading @@ -511,37 +478,6 @@ that message.`, Description: `Exits the BULLETIN program.`, Action: ActionExit, }, "EXTRACT": { Description: `Synonym for FILE command.`, }, "FILE": { Description: `Copies the current message to the named file. The file-name parameter is required. If the file exists, the message is appended to the file, unless the /NEW qualifier is specified. Format: FILE filename [message_number][-message_number1],[...] A range of messages to be copied can optionally be specified, i.e FILE. 2-5 . The key words CURRENT and LAST can also be specified in the range in, place of an actual number, i.e. CURRENT-LAST, 1-CURRENT, etc.`, MinArgs: 1, MaxArgs: 2, Flags: dclish.Flags{ "/ALL": { Description: ` Copies all the messages in the current folder.`, }, "/FF": { Description: ` Specifies that a form feed is placed between messages in the file.`, }, "/NEW": { Description: ` Specifies that a new file is to be created. Otherwise, if the specified file exists, the file would be appended to that file.`, }, }, }, "FIRST": { Description: `Specifies that the first message in the folder is to be read.`, Action: ActionFirst, Loading Loading @@ -608,12 +544,6 @@ where one left off after one has read a message. Format: LAST`, Action: ActionLast, Flags: dclish.Flags{ "/EDIT": { Description: ` Specifies that the editor is to be used to read the message. This is useful for scanning a long message.`, }, }, }, "MAIL": { Description: `Invokes the VAX/VMS Personal Mail Utility (MAIL) to send the message Loading @@ -630,10 +560,6 @@ specified as xxx%"""address""".`, MinArgs: 1, MaxArgs: 10, Flags: dclish.Flags{ "/EDIT": { Description: ` Specifies that the editor is to be used to edit the message before mailing it.`, }, "/SUBJECT": { Description: `/SUBJECT=text Loading Loading @@ -745,12 +671,6 @@ place of an actual number, i.e. CURRENT-LAST, 1-CURRENT, etc.`, through the messages and you encounter a particularly long message that you would like to skip over.`, Action: ActionNext, Flags: dclish.Flags{ "/EDIT": { Description: ` Specifies that the editor is to be used to read the message. This is useful for scanning a long message.`, }, }, }, "PRINT": { Description: `Queues a copy of the message you are currently reading (or have just Loading Loading @@ -841,10 +761,6 @@ the help on the SEEN command.`, "/ALL": { Description: ` Specifies to read all messages. Used after /MARKED, /UNMARKED, /SEEN, or /UNSEEN had been specified.`, }, "/EDIT": { Description: ` Specifies that the editor is to be used to read the message. This is useful for scanning a long message.`, }, "/MARKED": { Description: ` Specifies to read only messages that have been marked (marked messages Loading Loading @@ -910,19 +826,14 @@ read message with "RE:" preceeding it. Format and qualifiers is exactly the same as the ADD command except for /NOINDENT and /EXTRACT. Format: REPLY [file-name]`, MaxArgs: 1, REPLY`, Action: ActionReply, Flags: dclish.Flags{ "/EDIT": { Description: ` Specifies that the editor is to be used for creating the reply message.`, }, "/EXTRACT": { Description: ` Specifies that the text of the message should be included in the reply message. This qualifier is valid only when used with /EDIT. The text of the message is indented with > at the beginning of each line. This can be suppressed with /NOINDENT.`, message. This is the default - suppress with /NOEXTRACT. The text of the message is indented with > at the beginning of each line. This can be suppressed with /NOINDENT.`, }, "/INDENT": { Description: ` See /EXTRACT for information on this qualifier. Loading @@ -937,28 +848,23 @@ the same as the ADD command except for /NOINDENT and /EXTRACT. message to the owner of the currently read message. Format: RESPOND [file-name] RESPOND If you wish to use another method for sending the mail, define BULL_MAILER to point to a command procedure. This procedure will then be executed in place of MAIL, and the parameters passed to it are the username and subject of the message.`, MaxArgs: 1, Flags: dclish.Flags{ "/CC": { Description: `/CC=user[s] Specifies additional users that should receive the reply.`, OptArg: true, }, "/EDIT": { Description: ` Specifies that the editor is to be used for creating the reply mail message.`, }, "/EXTRACT": { Description: ` Specifies that the text of the message should be included in the reply mail message. This qualifier is valid only when used with /EDIT. The text of the message is indented with > at the beginning of each line. This can be suppressed with /NOINDENT.`, mail message. This is the default - suppress with /NOEXTRACT. The text of the message is indented with > at the beginning of each line. This can be suppressed with /NOINDENT.`, }, "/LIST": { Description: ` Specifies that the reply should also be sent to the network mailing Loading Loading @@ -1012,9 +918,6 @@ search can be aborted by typing a CTRL-C.`, MinArgs: 1, MaxArgs: 1, Flags: dclish.Flags{ "/EDIT": { Description: ` Specifies that the editor is to be used for reading the message.`, }, "/FOLDER": { Description: `/FOLDER=(folder,[...]) Loading
repl/messages.go +1 −3 Original line number Diff line number Diff line Loading @@ -151,7 +151,6 @@ func ActionAdd(cmd *dclish.Command) error { // ActionCurrent handles the `CURRENT` command. func ActionCurrent(_ *dclish.Command) error { // TODO: handle flags. msg, err := folders.ReadMessage(this.User.Login, this.Folder.Name, this.MsgID) if err != nil { return err Loading @@ -166,7 +165,6 @@ func ActionCurrent(_ *dclish.Command) error { // ActionBack handles the `BACK` command. func ActionBack(_ *dclish.Command) error { // TODO: handle flags. msgid := folders.PrevMsgid(this.User.Login, this.Folder.Name, this.MsgID) if msgid == 0 { fmt.Println("No previous messages") Loading Loading @@ -213,7 +211,6 @@ func ActionLast(_ *dclish.Command) error { // ActionNext handles the `NEXT` command. func ActionNext(_ *dclish.Command) error { // TODO: handle flags. msgid := folders.NextMsgid(this.User.Login, this.Folder.Name, this.MsgID) if msgid == 0 { fmt.Println("No next messages") Loading Loading @@ -257,6 +254,7 @@ func ActionPrint(cmd *dclish.Command) error { // ActionRead handles the `READ` command. func ActionRead(cmd *dclish.Command) error { // TODO: Implement the functionality of incrementing the message number *first* but not the first time the command is run. // TODO: handle flags. msgid := this.MsgID if len(cmd.Args) == 1 { Loading