[hackers] [libzahl] Misc work on the manual || Mattias Andrée

2016-05-16 Thread git
commit d998ab149b65c2a8e85e30d9405ae19d4e2ec54a
Author: Mattias Andrée 
AuthorDate: Mon May 16 18:01:44 2016 +0200
Commit: Mattias Andrée 
CommitDate: Mon May 16 18:01:44 2016 +0200

Misc work on the manual

Signed-off-by: Mattias Andrée 

diff --git a/doc/bit-operations.tex b/doc/bit-operations.tex
index 24e0155..c3fbe4a 100644
--- a/doc/bit-operations.tex
+++ b/doc/bit-operations.tex
@@ -1,7 +1,10 @@
 \chapter{Bit operations}
 \label{chap:Bit operations}
 
-TODO
+libzahl provides a number of functions that operate on
+bits. These can sometimes be used instead of arithmetic
+functions for increased performance. You should read
+the sections in order.
 
 \vspace{1cm}
 \minitoc
@@ -11,7 +14,48 @@ TODO
 \section{Boundary}
 \label{sec:Boundary}
 
-TODO % zbits zlsb
+To retrieve the index of the lowest set bit, use
+
+\begin{alltt}
+   size_t zlsb(z_t a);
+\end{alltt}
+
+\noindent
+It will return a zero-based index, that is, if the
+least significant bit is indeed set, it will return 0.
+
+If {\tt a} is a power of 2, it will return the power
+of which 2 is raised, effectively calculating the
+binary logarithm of {\tt a}. Note, this is only if
+{\tt a} is a power of two. More generally, it returns
+the number of trailing binary zeroes, if equivalently
+the number of times {\tt a} can evenly be divided by
+2. However, in the special case where $a = 0$,
+{\tt SIZE\_MAX} is returned.
+
+A similar function is
+
+\begin{alltt}
+   size_t zbit(z_t a);
+\end{alltt}
+
+\noindent
+It returns the minimal number of bits require to
+represent an integer. That is, $\lceil \log_2 a \rceil - 1$,
+or equivalently, the number of times {\tt a} can be
+divided by 2 before it gets the value 0. However, in
+the special case where $a = 0$, 1 is returned. 0 is
+never returned. If you want the value 0 to be returned
+if $a = 0$, write
+
+\begin{alltt}
+   zzero(a) ? 0 : zbits(a)
+\end{alltt}
+
+The definition ``it returns the minimal number
+of bits required to represent an integer,''
+holds true if $a = 0$, the other divisions
+do not hold true if $a = 0$.
 
 
 \newpage
@@ -161,7 +205,28 @@ divide-and-conquer algorithms.
 \section{Bit manipulation}
 \label{sec:Bit manipulation}
 
-TODO % zbset
+
+The function
+
+\begin{alltt}
+   zbset(z_t r, z_t a, size_t bit, int mode);
+\end{alltt}
+
+\noindent
+is used to manipulate single bits in {\tt a}. It will
+copy {\tt a} into {\tt r} and then, in {\tt r}, either
+set, clear, or flip, the bit with the index {\tt bit}
+— the least significant bit has the index 0. The
+action depend on the value of {\tt mode}:
+
+\begin{itemize}
+\item
+$mode > 0$ ($+1$): set
+\item
+$mode = 0$ ($0$): clear
+\item
+$mode < 0$ ($-1$): flip
+\end{itemize}
 
 
 \newpage
diff --git a/doc/not-implemented.tex b/doc/not-implemented.tex
index 186a413..eacedea 100644
--- a/doc/not-implemented.tex
+++ b/doc/not-implemented.tex
@@ -399,7 +399,10 @@ using the following algorithm:
\}
zfree(k), zfree(a);
\}
+\end{alltt}
 
+\newpage
+\begin{alltt}
void
fib(z_t f, z_t n)
\{
@@ -591,6 +594,11 @@ be improve by comparing character by
 character manually with using {\tt zxor}.
 
 
+\newpage
+\section{Miscellaneous}
+\label{sec:Miscellaneous}
+
+
 \subsection{Character retrieval}
 \label{sec:Character retrieval}
 
@@ -601,3 +609,76 @@ getu(z_t a)
 return zzero(a) ? 0 : a->chars[0];
 \}
 \end{alltt}
+
+\subsection{Fit test}
+\label{sec:Fit test}
+
+Some libraries have functions for testing
+whether a big integer is small enough to
+fit into an intrinsic type. Since libzahl
+does not provide conversion to intrinsic
+types this is irrelevant. But additionally,
+it can be implemented with a single
+one-line macro that does not have any
+side-effects.
+
+\begin{alltt}
+   #define fits_in(a, type)  (zbits(a) <= 8 * sizeof(type))
+   \textcolor{c}{/* \textrm{Just be sure the type is integral.} */}
+\end{alltt}
+
+
+\subsection{Reference duplication}
+\label{sec:Reference duplication}
+
+This could be useful for creating duplicates
+with modified sign. But only if neither
+{\tt r} or {\tt a} will be modified whilst
+both are in use. Because it is unsafe,
+fairly simple to create an implementation
+with acceptable performance — {\tt *r = *a},
+— and probably seldom useful, this has not
+be implemented.
+
+\begin{alltt}
+   int
+   refdup(z_t r, z_t a)
+   \{
+   \textcolor{c}{/* \textrm{Almost fully optimised, but perfectly 
portable} *r = *a; */}
+   r->sign= a->sign;
+   r->used= a->used;
+   r->alloced = a->alloced;
+   r->chars   = a->chars;
+   \}
+\end{alltt}
+
+
+\subsection{Variadic initialisation}
+\label{sec:Variadic initialisation}
+
+Must bignum libraries have variadic functions
+for initialisation and uninitialisation. This
+is not available in libzahl, because it is
+not useful enough and has performance overhead.
+And what's next, support {\tt va\_list},
+variadic addition, 

[hackers][vis][RFC][PATCH 1/2] Add autocompletion for current file contents

2016-05-16 Thread Silvan Jegen
We add some infrastructure in order to run a shell command and get its
output which we then can insert into vis.

This infrastructure we use to execute a shell command which sends all
unique words of the current file to dmenu. The word selected in dmenu
is then inserted into vis at all cursor positions.
---
 config.def.h |   1 +
 main.c   | 114 +++
 vis.c|   6 +++-
 vis.h|   1 +
 4 files changed, 121 insertions(+), 1 deletion(-)

diff --git a/config.def.h b/config.def.h
index 8699136..9e52102 100644
--- a/config.def.h
+++ b/config.def.h
@@ -319,6 +319,7 @@ static const KeyBinding bindings_insert[] = {
{ "",  ALIAS("<b) or new (arg->b) window */
 static const char *open_file_under_cursor(Vis*, const char *keys, const Arg 
*arg);
+/* Insert text chosen in external file dialog at cursor position(s) */
+static void insert_dialog_selection(Vis*, const char *cmdline, ...);
+/* Get output of external command */
+static char *get_output_of_external_command(Vis*, const char *argv[]);
+/* Autocomplete input text at cursor based on the words in the current file */
+static const char *autocomplete_file_text(Vis*, const char *keys, const Arg 
*arg);
 
 enum {
VIS_ACTION_EDITOR_SUSPEND,
@@ -307,6 +313,7 @@ enum {
VIS_ACTION_NUMBER_DECREMENT,
VIS_ACTION_OPEN_FILE_UNDER_CURSOR,
VIS_ACTION_OPEN_FILE_UNDER_CURSOR_NEW_WINDOW,
+   VIS_ACTION_FILE_TEXT_AUTOCOMPLETE,
VIS_ACTION_NOP,
 };
 
@@ -1211,6 +1218,11 @@ static const KeyAction vis_action[] = {
"Open file under the cursor in a new window",
open_file_under_cursor, { .b = true }
},
+   [VIS_ACTION_FILE_TEXT_AUTOCOMPLETE] = {
+   "autocomplete-file-text",
+   "Autocomplete text in file",
+   autocomplete_file_text,
+   },
[VIS_ACTION_NOP] = {
"nop",
"Ignore key, do nothing",
@@ -2093,6 +2105,108 @@ static const char *open_file_under_cursor(Vis *vis, 
const char *keys, const Arg
return keys;
 }
 
+ssize_t read_buffer(void *context, char *data, size_t len) {
+   buffer_append(context, data, len);
+   return len;
+}
+
+static char *get_output_of_external_command(Vis *vis, const char *argv[]) {
+   char *out = NULL;
+   Buffer bufout, buferr;
+   buffer_init();
+   buffer_init();
+
+   Filerange empty = text_range_empty();
+   int status = vis_pipe(vis, , argv, , read_buffer,
+   , read_buffer);
+
+   if (status != 0) {
+   vis_info_show(vis, "Command failed %s", 
buffer_content0());
+   } else {
+   out = malloc(bufout.len);
+   strncpy(out, buffer_content0(), buffer_length0());
+   out[buffer_length0()] = '\0';
+   }
+
+   buffer_release();
+   buffer_release();
+   return out;
+}
+
+// Caller has to free the allocated memory for the prefix
+static char *get_prefix_for_autocomplete(Vis *vis) {
+   View *view = vis_view(vis);
+   Cursor *c = view_cursors(view);
+   Text *txt = vis_text(vis);
+
+   Filerange r = text_object_word(txt, view_cursors_pos(c)-1);
+   if (!text_range_valid())
+   return NULL;
+
+   char *prefix = text_bytes_alloc0(txt, r.start, text_range_size());
+   char *check;
+   for (check = prefix; *check; check++) {
+   if (!isspace(*check))
+   break;
+   }
+   if (*check == '\0') {
+   vis_info_show(vis, "Autocompletion without prefix input is not 
valid.");
+   free(prefix);
+   return NULL;
+   }
+
+   return prefix;
+}
+
+static const char *autocomplete_file_text(Vis *vis, const char *keys, const 
Arg *arg) {
+   Win *win = vis_window(vis);
+   const char *fn = vis_window_filename(win);
+
+   char *prefix = get_prefix_for_autocomplete(vis);
+   if (!prefix)
+   return keys;
+
+   // TODO: get menu/dialog program to use from config?
+   insert_dialog_selection(vis, "cat '%s' | tr \" ;:$<>#?{}()[],.'\" '\n' 
| grep \"^%s\" | sort | uniq | dmenu | tr -d 

[hackers][vis][RFC][PATCH 0/2] Suggestion for basic autocomplete functionality

2016-05-16 Thread Silvan Jegen
Heyhey

I have implemented basic autocomplete functionality by sending the text
at cursor position as a context to shell commands and dmenu. The user
then chooses the autocompletion text he wants to use in dmenu which is
then inserted at cursor position.

Ideally the same approach should be used for code completion by sending
some context to a code completion daemon (like gocode[0] for example). The
daemon's output can then be sent to dmenu and selected by the user.

The patches are still rough but I did not want to invest more time
without knowing if such an approach would be considered for inclusion
or not. Let me know what you think.


Cheers,

Silvan


[0] https://github.com/nsf/gocode

Silvan Jegen (2):
  Add autocompletion for current file contents
  Add autocompletion for file names

 config.def.h |   2 +
 main.c   | 134 +++
 vis.c|   6 ++-
 vis.h|   1 +
 4 files changed, 142 insertions(+), 1 deletion(-)

-- 
2.8.2