about summary refs log blame commit diff stats
path: root/src/chat_session.c
blob: 2758d603c653798db2591bc654264854971f2195 (plain) (tree)
1
2
3
4
5
151
pre { line-height: 125%; } td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.V
/*
 * chat_session.c
 *
 * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
 *
 * This file is part of Profanity.
 *
 * Profanity 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.
 *
 * Profanity 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 Profanity.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give permission to
 * link the code of portions of this program with the OpenSSL library under
 * certain conditions as described in each individual source file, and
 * distribute linked combinations including the two.
 *
 * You must obey the GNU General Public License in all respects for all of the
 * code used other than OpenSSL. If you modify file(s) with this exception, you
 * may extend this exception to your version of the file(s), but you are not
 * obligated to do so. If you do not wish to do so, delete this exception
 * statement from your version. If you delete this exception statement from all
 * source files in the program, then also delete it here.
 *
 */

#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include <glib.h>

#include "chat_session.h"
#include "config/preferences.h"
#include "log.h"
#include "xmpp/xmpp.h"

static GHashTable *sessions;

static void
_chat_session_new(const char * const barejid, const char * const resource,
    gboolean resource_override, gboolean send_states)
{
    assert(barejid != NULL);
    assert(resource != NULL);

    ChatSession *new_session = malloc(sizeof(struct chat_session_t));
    new_session->barejid = strdup(barejid);
    new_session->resource = strdup(resource);
    new_session->resource_override = resource_override;
    new_session->send_states = send_states;

    g_hash_table_replace(sessions, strdup(barejid), new_session);
}

static void
_chat_session_free(ChatSession *session)
{
    if (session) {
        free(session->barejid);
        free(session->resource);
        free(session);
    }
}

void
chat_sessions_init(void)
{
    sessions = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
        (GDestroyNotify)_chat_session_free);
}

void
chat_sessions_clear(void)
{
    if (sessions)
        g_hash_table_remove_all(sessions);
}

void
chat_session_resource_override(const char * const barejid, const char * const resource)
{
    _chat_session_new(barejid, resource, TRUE, TRUE);
}

ChatSession*
chat_session_get(const char * const barejid)
{
    return g_hash_table_lookup(sessions, barejid);
}

void
chat_session_recipient_gone(const char * const barejid, const char * const resource)
{
    assert(barejid != NULL);
    assert(resource != NULL);

    ChatSession *session = g_hash_table_lookup(sessions, barejid);
    if (session && g_strcmp0(session->resource, resource) == 0) {
        if (!session->resource_override) {
            chat_session_remove(barejid);
        }
    }
}

void
chat_session_recipient_typing(const char * const barejid, const char * const resource)
{
    chat_session_recipient_active(barejid, resource, TRUE);
}

void
chat_session_recipient_paused(const char * const barejid, const char * const resource)
{
    chat_session_recipient_active(barejid, resource, TRUE);
}

void
chat_session_recipient_inactive(const char * const barejid, const char * const resource)
{
    chat_session_recipient_active(barejid, resource, TRUE);
}

void
chat_session_recipient_active(const char * const barejid, const char * const resource,
    gboolean send_states)
{
    assert(barejid != NULL);
    assert(resource != NULL);

    ChatSession *session = g_hash_table_lookup(sessions, barejid);
    if (session) {
        // session exists with resource, update chat_states
        if (g_strcmp0(session->resource, resource) == 0) {
            session->send_states = send_states;
        // session exists with different resource and no override, replace
        } else if (!session->resource_override) {
            _chat_session_new(barejid, resource, FALSE, send_states);
        }

    // no session, create one
    } else {
        _chat_session_new(barejid, resource, FALSE, send_states);
    }
}

void
chat_session_remove(const char * const barejid)
{
    g_hash_table_remove(sessions, barejid);
}
s omitted, in which case the default application is used. I<flags> change the way the application is executed and are described in their own section in this man page. The I<mode> is a number that specifies which application to use. The list of applications is generated by the external file opener "rifle" and can be displayed when pressing "r" in ranger. Note that if you specify an application, the mode is ignored. =item pmap I<key> I<command> Binds keys for the pager. Works like the C<map> command. =item punmap [I<keys ...>] Removes key mappings of the pager. Works like the C<unmap> command. =item quit Like quit!, but closes only this tab if multiple tabs are open. =item quit! Quit ranger. The current directory will be bookmarked as ' so you can re-enter it by typing `` or '' the next time you start ranger. =item relink I<newpath> Change the link destination of the current symlink file to <newpath>. First <tab> will load the original link. =item rename I<newname> Rename the current file. If a file with that name already exists, the renaming will fail. Also try the key binding A for appending something to a file name. =item save_copy_buffer Save the copy buffer to I<~/.config/ranger/copy_buffer>. This can be used to pass the list of copied files to another ranger instance. =item scout [-I<flags>...] [--] I<pattern> Swiss army knife command for searching, traveling and filtering files. The command takes various flags as arguments which can be used to influence its behaviour: -a = automatically open a file on unambiguous match -e = open the selected file when pressing enter -f = filter files that match the current search pattern -g = interpret pattern as a glob pattern -i = ignore the letter case of the files -k = keep the console open when changing a directory with the command -l = letter skipping; e.g. allow "rdme" to match the file "readme" -m = mark the matching files after pressing enter -M = unmark the matching files after pressing enter -p = permanent filter: hide non-matching files after pressing enter -s = smart case; like -i unless pattern contains upper case letters -t = apply filter and search pattern as you type -v = inverts the match Multiple flags can be combined. For example, ":scout -gpt" would create a :filter-like command using globbing. =item search I<pattern> Search files in the current directory that match the given (case insensitive) regular expression pattern. =item search_inc I<pattern> Search files in the current directory that match the given (case insensitive) regular expression pattern. This command gets you to matching files as you type. =item set I<option> I<value> Assigns a new value to an option. Valid options are listed in the settings section. Use tab completion to get the current value of an option, though this doesn't work for functions and regular expressions. Valid values are: setting type | example values ---------------+---------------------------- bool | true, false integer | 1, 23, 1337 string | foo, hello world list | 1,2,3,4 none | none =item setlocal [path=I<path>] I<option> I<value> Assigns a new value to an option, but locally for the directory given by I<path>. This means, that this option only takes effect when visiting that directory. If no path is given, uses the current directory. =item shell [-I<flags>] I<command> Run a shell command. I<flags> are discussed in their own section. =item terminal Spawns the I<x-terminal-emulator> starting in the current directory. =item tmap I<key> I<command> Binds keys for the taskview. Works like the C<map> command. =item touch I<filename> Creates an empty file with the name I<filename>, unless it already exists. =item travel I<pattern> Filters the current directory for files containing the letters in the string, possibly with other letters in between. The filter is applied as you type. When only one directory is left, it is entered and the console is automatically reopened, allowing for fast travel. To close the console, press ESC or execute a file. =item tunmap [I<keys ...>] Removes key mappings of the taskview. Works like the C<unmap> command. =item unmap [I<keys> ...] Removes the given key mappings in the "browser" context. To unmap key bindings in the console, taskview, or pager use "cunmap", "tunmap" or "punmap". =item unmark I<pattern> Unmark all files matching a regular expression pattern. =item unmark_tag [I<tags>] Unmark all tags that are tagged with either of the given tags. When leaving out the tag argument, all tagged files are unmarked. =back =head1 FILES ranger reads several configuration files which are located in F<$HOME/.config/ranger> or F<$XDG_CONFIG_HOME/ranger> if $XDG_CONFIG_HOME is defined. You can use the --copy-config option to obtain the default configuration files. Each of the files contains further documentation. You don't need to copy the whole file though, most configuration files are overlaid on top of the defaults (F<commands.py>, F<rc.conf>) or can be sub-classed (F<colorschemes>). When starting ranger with the B<--clean> option, it will not access or create any of these files. =head2 CONFIGURATION =over 10 =item rc.conf Contains a list of commands which are executed on startup. Mostly key bindings and settings are defined here. =item commands.py A python module that defines commands which can be used in ranger's console by typing ":" or in the rc.conf file. =item rifle.conf This is the configuration file for the built-in file launcher called "rifle". =item scope.sh This is a script that handles file previews. When the options I<use_preview_script> and I<preview_files> are set, the program specified in the option I<preview_script> is run and its output and/or exit code determines rangers reaction. =item colorschemes/ Colorschemes can be placed here. =item plugins/ Plugins can be placed here. =back =head2 STORAGE =over 10 =item bookmarks This file contains a list of bookmarks. The syntax is /^(.):(.*)$/. The first character is the bookmark key and the rest after the colon is the path to the file. In ranger, bookmarks can be set by typing m<key>, accessed by typing '<key> and deleted by typing um<key>. =item copy_buffer When running the command :save_copy_buffer, the paths of all currently copied files are saved in this file. You can later run :load_copy_buffer to copy the same files again, pass them to another ranger instance or process them in a script. =item history Contains a list of commands that have been previously typed in. =item tagged Contains a list of tagged files. The syntax is /^(.:)?(.*)$/ where the first letter is the optional name of the tag and the rest after the optional colon is the path to the file. In ranger, tags can be set by pressing t and removed with T. To assign a named tag, type "<tagname>. =back =head1 ENVIRONMENT These environment variables have an effect on ranger: =over 8 =item RANGER_LEVEL ranger sets this environment variable to "1" or increments it if it already exists. External programs can determine whether they were spawned from ranger by checking for this variable. =item RANGER_LOAD_DEFAULT_RC If this variable is set to FALSE, ranger will not load the default rc.conf. This can save time if you copied the whole rc.conf to ~/.config/ranger/ and don't need the default one at all. =item EDITOR Defines the editor to be used for the "E" key. Defaults to "nano". =item SHELL Defines the shell that ranger is going to use with the :shell command and the "S" key. Defaults to "/bin/sh". =item TERMCMD Defines the terminal emulator command that ranger is going to use with the :terminal command and the "t" run flag. Defaults to "xterm". =item XDG_CONFIG_HOME Specifies the directory for configuration files. Defaults to F<$HOME/.config>. =item PYTHONOPTIMIZE This variable determines the optimize level of python. Using PYTHONOPTIMIZE=1 (like python -O) will make python discard assertion statements. You will gain efficiency at the cost of losing some debug info. Using PYTHONOPTIMIZE=2 (like python -OO) will additionally discard any docstrings. Using this will disable the <F1> key on commands. =item W3MIMGDISPLAY_PATH By changing this variable, you can change the path of the executable file for image previews. By default, it is set to F</usr/lib/w3m/w3mimgdisplay>. =back =head1 EXAMPLES There are various examples on how to extend ranger with plugins or combine ranger with other programs. These can be found in the F</usr/share/doc/ranger/examples/> directory, or the F<doc/ranger/> that is provided along with the source code. =head1 LICENSE GNU General Public License 3 or (at your option) any later version. =head1 LINKS =over =item Download: L<http://ranger.nongnu.org/ranger-stable.tar.gz> =item The project page: L<http://ranger.nongnu.org/> =item The mailing list: L<http://savannah.nongnu.org/mail/?group=ranger> =back ranger is maintained with the git version control system. To fetch a fresh copy, run: git clone git://git.savannah.nongnu.org/ranger.git =head1 SEE ALSO rifle(1) =head1 BUGS Report bugs here: L<http://savannah.nongnu.org/bugs/?group=ranger> Please include as much relevant information as possible. For the most diagnostic output, run ranger like this: C<PYTHONOPTIMIZE= ranger --debug>