summary refs log tree commit diff stats
path: root/lib/wrappers/readline/history.nim
blob: caa857ceb4ddaa8daa5ec0d49a8e9d54f2ae9f5c (plain) (blame)
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# history.h -- the names of functions that you can call in history. 
# Copyright (C) 1989-2009 Free Software Foundation, Inc.
#
#   This file contains the GNU History Library (History), a set of
#   routines for managing the text of previously typed lines.
#
#   History 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 3 of the License, or
#   (at your option) any later version.
#
#   History 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.
#
#   You should have received a copy of the GNU General Public License
#   along with History.  If not, see <http://www.gnu.org/licenses/>.
#

{.deadCodeElim: on.}

import readline

const 
  historyDll = readlineDll

import times, rltypedefs

type 
  Thistdata* = pointer

# The structure used to store a history entry. 

type 
  THIST_ENTRY*{.pure, final.} = object 
    line*: cstring
    timestamp*: cstring       # char * rather than time_t for read/write 
    data*: Thistdata


# Size of the history-library-managed space in history entry HS. 

template HISTENT_BYTES*(hs: expr): expr = 
  (strlen(hs.line) + strlen(hs.timestamp))

# A structure used to pass the current state of the history stuff around. 

type 
  THISTORY_STATE*{.pure, final.} = object 
    entries*: ptr ptr THIST_ENTRY # Pointer to the entries themselves. 
    offset*: cint             # The location pointer within this array. 
    length*: cint             # Number of elements within this array. 
    size*: cint               # Number of slots allocated to this array. 
    flags*: cint


# Flag values for the `flags' member of HISTORY_STATE. 

const 
  HS_STIFLED* = 0x00000001

# Initialization and state management. 
# Begin a session in which the history functions might be used.  This
#   just initializes the interactive variables. 

proc using_history*(){.cdecl, importc: "using_history", dynlib: historyDll.}
# Return the current HISTORY_STATE of the history. 

proc history_get_history_state*(): ptr THISTORY_STATE{.cdecl, 
    importc: "history_get_history_state", dynlib: historyDll.}
# Set the state of the current history array to STATE. 

proc history_set_history_state*(a2: ptr THISTORY_STATE){.cdecl, 
    importc: "history_set_history_state", dynlib: historyDll.}
# Manage the history list. 
# Place STRING at the end of the history list.
#   The associated data field (if any) is set to NULL. 

proc add_history*(a2: cstring){.cdecl, importc: "add_history", 
                                dynlib: historyDll.}
# Change the timestamp associated with the most recent history entry to
#   STRING. 

proc add_history_time*(a2: cstring){.cdecl, importc: "add_history_time", 
                                     dynlib: historyDll.}
# A reasonably useless function, only here for completeness.  WHICH
#   is the magic number that tells us which element to delete.  The
#   elements are numbered from 0. 

proc remove_history*(a2: cint): ptr THIST_ENTRY{.cdecl, 
    importc: "remove_history", dynlib: historyDll.}
# Free the history entry H and return any application-specific data
#   associated with it. 

proc free_history_entry*(a2: ptr THIST_ENTRY): Thistdata{.cdecl, 
    importc: "free_history_entry", dynlib: historyDll.}
# Make the history entry at WHICH have LINE and DATA.  This returns
#   the old entry so you can dispose of the data.  In the case of an
#   invalid WHICH, a NULL pointer is returned. 

proc replace_history_entry*(a2: cint, a3: cstring, a4: Thistdata): ptr THIST_ENTRY{.
    cdecl, importc: "replace_history_entry", dynlib: historyDll.}
# Clear the history list and start over. 

proc clear_history*(){.cdecl, importc: "clear_history", dynlib: historyDll.}
# Stifle the history list, remembering only MAX number of entries. 

proc stifle_history*(a2: cint){.cdecl, importc: "stifle_history", 
                                dynlib: historyDll.}
# Stop stifling the history.  This returns the previous amount the
#   history was stifled by.  The value is positive if the history was
#   stifled, negative if it wasn't. 

proc unstifle_history*(): cint{.cdecl, importc: "unstifle_history", 
                                dynlib: historyDll.}
# Return 1 if the history is stifled, 0 if it is not. 

proc history_is_stifled*(): cint{.cdecl, importc: "history_is_stifled", 
                                  dynlib: historyDll.}
# Information about the history list. 
# Return a NULL terminated array of HIST_ENTRY which is the current input
#   history.  Element 0 of this list is the beginning of time.  If there
#   is no history, return NULL. 

proc history_list*(): ptr ptr THIST_ENTRY{.cdecl, importc: "history_list", 
    dynlib: historyDll.}
# Returns the number which says what history element we are now
#   looking at.  

proc where_history*(): cint{.cdecl, importc: "where_history", dynlib: historyDll.}
# Return the history entry at the current position, as determined by
#   history_offset.  If there is no entry there, return a NULL pointer. 

proc current_history*(): ptr THIST_ENTRY{.cdecl, importc: "current_history", 
    dynlib: historyDll.}
# Return the history entry which is logically at OFFSET in the history
#   array.  OFFSET is relative to history_base. 

proc history_get*(a2: cint): ptr THIST_ENTRY{.cdecl, importc: "history_get", 
    dynlib: historyDll.}
# Return the timestamp associated with the HIST_ENTRY * passed as an
#   argument 

proc history_get_time*(a2: ptr THIST_ENTRY): Time{.cdecl, 
    importc: "history_get_time", dynlib: historyDll.}
# Return the number of bytes that the primary history entries are using.
#   This just adds up the lengths of the_history->lines. 

proc history_total_bytes*(): cint{.cdecl, importc: "history_total_bytes", 
                                   dynlib: historyDll.}
# Moving around the history list. 
# Set the position in the history list to POS. 

proc history_set_pos*(a2: cint): cint{.cdecl, importc: "history_set_pos", 
                                       dynlib: historyDll.}
# Back up history_offset to the previous history entry, and return
#   a pointer to that entry.  If there is no previous entry, return
#   a NULL pointer. 

proc previous_history*(): ptr THIST_ENTRY{.cdecl, importc: "previous_history", 
    dynlib: historyDll.}
# Move history_offset forward to the next item in the input_history,
#   and return the a pointer to that entry.  If there is no next entry,
#   return a NULL pointer. 

proc next_history*(): ptr THIST_ENTRY{.cdecl, importc: "next_history", 
                                       dynlib: historyDll.}
# Searching the history list. 
# Search the history for STRING, starting at history_offset.
#   If DIRECTION < 0, then the search is through previous entries,
#   else through subsequent.  If the string is found, then
#   current_history () is the history entry, and the value of this function
#   is the offset in the line of that history entry that the string was
#   found in.  Otherwise, nothing is changed, and a -1 is returned. 

proc history_search*(a2: cstring, a3: cint): cint{.cdecl, 
    importc: "history_search", dynlib: historyDll.}
# Search the history for STRING, starting at history_offset.
#   The search is anchored: matching lines must begin with string.
#   DIRECTION is as in history_search(). 

proc history_search_prefix*(a2: cstring, a3: cint): cint{.cdecl, 
    importc: "history_search_prefix", dynlib: historyDll.}
# Search for STRING in the history list, starting at POS, an
#   absolute index into the list.  DIR, if negative, says to search
#   backwards from POS, else forwards.
#   Returns the absolute index of the history element where STRING
#   was found, or -1 otherwise. 

proc history_search_pos*(a2: cstring, a3: cint, a4: cint): cint{.cdecl, 
    importc: "history_search_pos", dynlib: historyDll.}
# Managing the history file. 
# Add the contents of FILENAME to the history list, a line at a time.
#   If FILENAME is NULL, then read from ~/.history.  Returns 0 if
#   successful, or errno if not. 

proc read_history*(a2: cstring): cint{.cdecl, importc: "read_history", 
                                       dynlib: historyDll.}
# Read a range of lines from FILENAME, adding them to the history list.
#   Start reading at the FROM'th line and end at the TO'th.  If FROM
#   is zero, start at the beginning.  If TO is less than FROM, read
#   until the end of the file.  If FILENAME is NULL, then read from
#   ~/.history.  Returns 0 if successful, or errno if not. 

proc read_history_range*(a2: cstring, a3: cint, a4: cint): cint{.cdecl, 
    importc: "read_history_range", dynlib: historyDll.}
# Write the current history to FILENAME.  If FILENAME is NULL,
#   then write the history list to ~/.history.  Values returned
#   are as in read_history ().  

proc write_history*(a2: cstring): cint{.cdecl, importc: "write_history", 
                                        dynlib: historyDll.}
# Append NELEMENT entries to FILENAME.  The entries appended are from
#   the end of the list minus NELEMENTs up to the end of the list. 

proc append_history*(a2: cint, a3: cstring): cint{.cdecl, 
    importc: "append_history", dynlib: historyDll.}
# Truncate the history file, leaving only the last NLINES lines. 

proc history_truncate_file*(a2: cstring, a3: cint): cint{.cdecl, 
    importc: "history_truncate_file", dynlib: historyDll.}
# History expansion. 
# Expand the string STRING, placing the result into OUTPUT, a pointer
#   to a string.  Returns:
#
#   0) If no expansions took place (or, if the only change in
#      the text was the de-slashifying of the history expansion
#      character)
#   1) If expansions did take place
#  -1) If there was an error in expansion.
#   2) If the returned line should just be printed.
#
#  If an error ocurred in expansion, then OUTPUT contains a descriptive
#  error message. 

proc history_expand*(a2: cstring, a3: cstringArray): cint{.cdecl, 
    importc: "history_expand", dynlib: historyDll.}
# Extract a string segment consisting of the FIRST through LAST
#   arguments present in STRING.  Arguments are broken up as in
#   the shell. 

proc history_arg_extract*(a2: cint, a3: cint, a4: cstring): cstring{.cdecl, 
    importc: "history_arg_extract", dynlib: historyDll.}
# Return the text of the history event beginning at the current
#   offset into STRING.  Pass STRING with *INDEX equal to the
#   history_expansion_char that begins this specification.
#   DELIMITING_QUOTE is a character that is allowed to end the string
#   specification for what to search for in addition to the normal
#   characters `:', ` ', `\t', `\n', and sometimes `?'. 

proc get_history_event*(a2: cstring, a3: ptr cint, a4: cint): cstring{.cdecl, 
    importc: "get_history_event", dynlib: historyDll.}
# Return an array of tokens, much as the shell might.  The tokens are
#   parsed out of STRING. 

proc history_tokenize*(a2: cstring): cstringArray{.cdecl, 
    importc: "history_tokenize", dynlib: historyDll.}
when false: 
  # Exported history variables. 
  var history_base*{.importc: "history_base", dynlib: historyDll.}: cint
  var history_length*{.importc: "history_length", dynlib: historyDll.}: cint
  var history_max_entries*{.importc: "history_max_entries", dynlib: historyDll.}: cint
  var history_expansion_char*{.importc: "history_expansion_char", 
                               dynlib: historyDll.}: char
  var history_subst_char*{.importc: "history_subst_char", dynlib: historyDll.}: char
  var history_word_delimiters*{.importc: "history_word_delimiters", 
                                dynlib: historyDll.}: cstring
  var history_comment_char*{.importc: "history_comment_char", dynlib: historyDll.}: char
  var history_no_expand_chars*{.importc: "history_no_expand_chars", 
                                dynlib: historyDll.}: cstring
  var history_search_delimiter_chars*{.importc: "history_search_delimiter_chars", 
                                       dynlib: historyDll.}: cstring
  var history_quotes_inhibit_expansion*{.
      importc: "history_quotes_inhibit_expansion", dynlib: historyDll.}: cint
  var history_write_timestamps*{.importc: "history_write_timestamps", 
                                 dynlib: historyDll.}: cint